UVa 1638 (递推) Pole Arrangement

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

题意:

有长度为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 <cstdio>
 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 }

代码君

时间: 2024-10-18 09:45:38

UVa 1638 (递推) Pole Arrangement的相关文章

UVa 580 (递推) Critical Mass

题意: 有两种盒子分别装有铀(U)和铅(L),现在把n个盒子排成一列(两种盒子均足够多),而且要求至少有3个铀放在一起,问有多少种排放方法. 分析: n个盒子排成一列,共有2n中方案,设其中符合要求的为f(n)种. f(n)可由下面两种情况递推出来: 前n-1个盒子的摆放满足要求,则第n个盒子可以摆放U也可以摆放L,共有2×f(n-1)中方案 前n-1个盒子不满足要求,要使前n个盒子满足要求,则第n-2.n-1.n个盒子一定是U.又因为前面的假设,所以第n-3个盒子一定是L(否则前n-1个盒子满

UVa 1645 (递推) Count

题意: 有多少个n个节点的有根树,满足每层节点的子节点个数相同,输出该数目除以1e9+7的余数. 分析: 这种题目就属于那种,看起来很高冷,读完题更高冷.想了N久想不出来,一搜题解,卧槽,这么sb的题我都不会. 言归正传,根据题意,这棵树是关于根节点对称的,对称性非常好,根节点下面的子树也完全相同. 所以就有了如下递推关系: 1 #include <cstdio> 2 #include <cmath> 3 4 const int maxn = 1000; 5 const int M

UVa 1647 (递推) Computer Transformation

题意: 有一个01串,每一步都会将所有的0变为10,将所有的1变为01,串最开始为1. 求第n步之后,00的个数 分析: 刚开始想的时候还是比较乱的,我还纠结了一下000中算是有1个00还是2个00 最终想明白后,并不会出现这样的子串. 总结了几个要点: 第n步之后,串的长度为2n,且0和1的个数相等,分别为2n-1 1经过两步变化为1001,所以每个1经过两步变化就会得到一个00,而且这个00分别被左右两边一个1包围着,不会与其他数字凑出额外的00 0经过两步变化为0110,所以00就会变成0

UVa 1646 (递推 JAVA大数) Edge Case

题意: 有n个点围成一圈,这n个点的匹配就是没有公共点的边集(这些边只能连接一圈中相邻的两点),求所有匹配的个数. 额,我不会分析..=_=|| 算了几个数,找找规律发现它满足斐波那契数列的递推关系,f(n) = f(n-1) + f(n-2) 自从会用了Java的BigInteger,就懒得写C的高精度了. 1 import java.io.*; 2 import java.util.*; 3 import java.math.*; 4 5 public class Main 6 { 7 st

UVA 11000- Bee 递推

In Africa there is a very special species of bee. Every year, the female bees of such species give birthto one male bee, while the male bees give birth to one male bee and one female bee, and then they die!Now scientists have accidentally found one “

UVa 1638 Pole Arrangement【递推】

题意:给出n根高度为1,2,3,---n的杆子,从左边能看到l根,右边能够看到r根,问有多少种可能 看的紫书的思路 先假设已经安排好了高度为2---i的杆子, 那么高度为1的杆子的放置方法有三种情况 放在最左边:从左边看得见,右边看不见 放在最右边:从右边看得见,左边看不见 放在中间,有i-2个空位可以插,左右都看不见 所以可以写出递推关系: d[i][j][k]=d[i-1][j-1][k]+d[i-1][j][k-1]+d[i-1][j][k]*(i-2); 1 #include<iostr

UVa 1638 Pole Arrangement

递推. 设f[柱子数量][从左边能看到的数量][从右边能看到的数量]=方案数 假设2~i高度的柱子都已经安排好,现在要插入高度为1的柱子.若它放在最左边,左边可见数量+1,放在最右边,右边可见数量+1,放在中间(有i-2个可能位置),左右可见数量不变. 递推完一个高度i时,假设把所有在场的柱子都拔高1单位高度,此时方案数不变,再加一个高度为1的柱子进去…… 1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)

【UVA】12034-Race(递推,组合数打表)

递推公式,假设第一名有i个人并列,那么: f[n] = C(n,i) * f[n - i]; 打出1 ~ 1000的所有组合数,之后记忆化搜索,需要打表. 14026995 12034 Race Accepted C++ 0.032 2014-08-12 11:47:47 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector&g