博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVa 1638 (递推) Pole Arrangement
阅读量:5292 次
发布时间:2019-06-14

本文共 1038 字,大约阅读时间需要 3 分钟。

很遗憾,这么好的一道题,自己没想出来,也许太心急了吧。

题意:

有长度为1、2、3...n的n个杆子排成一行。问从左到右看能看到l个杆子,从右往左看能看到r个杆子,有多少种排列方法。

分析:

设状态d(i, j, k)表示i(i≥2)个长度各不相同的杆子,从左往右看能看到j个杆子,从右往左看能看到k个杆子的排列方法。现在假设除了最短的那个杆子,其他i-1个杆子的位置都已排好。那么考虑最短的杆子的位置,有三种决策:

  • 将最短的放到最左边,这样左视图中看到的杆子数加一,右视图不变。
  • 将最短的放到最右边,这样右视图中看到的杆子数加一,左视图不变。
  • 将最短的放在中间,这样从左侧或者从右侧都不会被看到,共有i-2中放法。

因此状态转移方程为:d(i, j, k) = d(i-1, j-1, k) + d(i-1, j, k-1) + (i-2)*d(i-1, j, k) //分别对应三种决策

1 #include 
2 typedef long long LL; 3 const int maxn = 20; 4 LL f[22][22][22]; 5 6 void Init() 7 { 8 f[1][1][1] = 1; 9 for(int i = 2; i <= maxn; ++i)10 for(int j = 1; j <= i; ++j)11 for(int k = 1; j + k - 1 <= i; ++k)12 f[i][j][k] = f[i-1][j-1][k] + f[i-1][j][k-1] + (i-2)*f[i-1][j][k];13 }14 15 int main()16 {17 Init();18 int T;19 scanf("%d", &T);20 while(T--)21 {22 int n, l, r;23 scanf("%d%d%d", &n, &l, &r);24 printf("%lld\n", f[n][l][r]);25 }26 27 return 0;28 }
代码君

 

转载于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4178755.html

你可能感兴趣的文章
数据处理之文件读写
查看>>
Openssl生成证书
查看>>
工具使用及环境搭建
查看>>
单例模式 分析 代码优化
查看>>
[心情琐记]-为什么我选择做一个程序员?【谨以此文献给初入技术之路的纯白少年】...
查看>>
DBCC CHECKDB 数据库或表修复
查看>>
PHP的分页
查看>>
ZOJ 3791 An Easy Game [组合计数]
查看>>
DOM
查看>>
AOJ/搜索与递归及分治法习题集
查看>>
express
查看>>
iOS视图弹出、平移、旋转、翻转、剪切等变换效果实现
查看>>
iOS获取用户设备崩溃日志并分析
查看>>
String类
查看>>
1、IO概述及File类
查看>>
[bzoj3531][Sdoi2014]旅行
查看>>
3.将模型添加到 ASP.NET Core MVC 应用
查看>>
Google TensorFlow for GPU安装、配置大坑
查看>>
【转】Android开发之如何保证Service不被杀掉(broadcast+system/app)
查看>>
什么是RUP,什么是敏捷开发,什么是XP(极限编程)
查看>>