当前位置 : 主页 > 网络编程 > 其它编程 >

UVALive6486Skyscrapers简单动态规划

来源:互联网 收集:自由互联 发布时间:2023-07-02
题意:有N个格子排成一排,在每个格子里填上1到N的数(每个只能填一次),分别代表每个格子的高度。现在给你两个数left和right,分别表示从左往右看,和从右往左看,能看到的格 题意
题意:有N个格子排成一排,在每个格子里填上1到N的数(每个只能填一次),分别代表每个格子的高度。现在给你两个数left和right,分别表示从左往右看,和从右往左看,能看到的格

题意:

  有N个格子排成一排,在每个格子里填上1到N的数(每个只能填一次),分别代表每个格子的高度。现在给你两个数left和right,分别表示从左往右看,和从右往左看,能看到的格子数。问有多少种情况。

数据范围: N<5000;

思路:

  首先枚举最高的一块,在最高的格子的后面的格子都一定会被挡住。所以,除了最高的那一格之外,从左边能看到的格子,从右边一定看不到;从右边能看到的也是一样。

  因此,除了最高的那个格子,左边的是否能被看见,和右边的无关。所以,我们可以以最高的格子为界,把这一排格子分成左右两部分。

  在这样子,我们就可以把左边和右边看成是一种情况:把n个高度不等的方块排成一列,要求从前面只能看到k个,有多少种。

    我们把上面问题(n个格子,看见k个)的结果记为f[n, k]。

    对于上面那个问题,我们考虑两种情况:最高的放在最后,和最高的不放在最后。

  1. 如果最高的放最后,因为最高的一定不会被挡住,所以,前面n-1个格子,需要被看见k-1个。

  2. 如果最高的不放在最后,那么,最后一格一定会被挡住(因为最高的在它前面,而且会挡住他),所以前面n-1个格子,仍然需要被看见k个。

上面第一种,情况只有一种;而第二种情况有n-1种(把n-1个不是最高的中任意一个放到最后都满足)。

  所以 f[n, k] = f[n-1, k-1] + (n-1)*f[n-1, k]。

  另外就是边界情况,k=1的时候,这样一定就是最高的放最前面,后面随便放,所以就是 f[n, 1] = (n-1)!。

  还有就是,组合数可以用杨辉三角来求,这个是学弟说的,本人数学功底太差 0 0、

代码:

bubuko.com,布布扣bubuko.com,布布扣

1 #include 2 #include 3 #include 4 #include 5 6 using namespace std; 7 8 typedef long long ll; 9 const int MAXN = 5005;10 const ll MOD = (ll)1e9+7.0;11 12 13 ll dp[MAXN][MAXN];14 ll C[MAXN][MAXN];15 ll ni[MAXN];16 17 int n, l, r;18 ll ans;19 20 int main()21 {22 #ifdef Phantom0123 freopen("in.txt", "r", stdin);24 freopen("my.out", "w", stdout);25 #endif // Phantom0126 27 dp[0][0] = dp[1][1] = 1;28 for (int i = 1; i UVALive 6486 Skyscrapers 简单动态规划,布布扣,bubuko.com

网友评论