您的位置:首页 > 其它

codeforce 479E - Riding in a Lift

2014-11-05 15:00 381 查看
题目链接:http://codeforces.com/problemset/problem/479/E

题目大意:N层楼,人在A层,秘密实验室在B层,每次移动必须满足:x为当前所在层,y为目标层,|x
- y| < |x - b|,求移动K次有多少不同的路径。

题目分析:dp[i][j]代表i为当前层数为i,j次移动的方案数。当a<b时,所有的x都不会超过b,设第j-1次停在x层,则第i层所有大于x小于b的点都可以取,对于小于x的点,x-j<=b-x-1, 整理得:x<=(b+j-1)/2; 转移方程为:dp[i][j] = sum[x][j - 1] - dp[i][j - 1]

代码参考:

#include<cstdio>
using namespace std;
const int N = 5009;
const int MOD = 1e9 + 7;
int dp

, sum

;
//sum[i][j]代表最高到达的楼层是i,移动了j步时的方案数
int main()
{
int n, a, b, k, i, j;
scanf("%d%d%d%d", &n, &a, &b, &k);
if(a > b) {//如果不是a<b的情况, 就类似于将楼层倒置计算
a = n - a + 1;
b = n - b + 1;
}
dp[a][0] = 1;//一开始移动0步的时候,人在a楼的方案数肯定为1
for(i = 1; i < b; ++ i) sum[i][0] = sum[i - 1][0] + dp[i][0];
for(j = 1; j <= k; ++ j) {
for(i = 1; i < b; ++ i) {
int x = (b + i - 1) / 2;//j-1次移动时的最高楼层
dp[i][j] = sum[x][j - 1] - dp[i][j - 1];//这里要减去本来就在i层的情况,因为不能静止
if(dp[i][j] < 0) dp[i][j] += MOD;//防止出现负数
sum[i][j] = sum[i - 1][j] + dp[i][j];//在原来的基础上加上到达i层的方案数
if(sum[i][j] >= MOD) sum[i][j] -= MOD;//取余
}
}
printf("%d\n", sum[b-1][k]);//答案为移动k步,最大到达b-1的方案数
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces dp