Codeforces Round #274 (Div. 2) E. Riding in a Lift DP

链接:

http://codeforces.com/contest/479/problem/E

题意:

有一个电梯一共n层,你现在在a层,不能去b层,现在你会进行k次移动

每次移动可以从x移动到y     x,y满足x - y| < |x - b| ,问你一共有多少种不同的操作

题解:

动态规划 dp[step][cnt]表示当前走了step步,现在在cnt层的次数,

开始用树状数组记录上一个step的次数,然后果然超时了 5000的数据 n^2lgn跑不过啊

而且还wa了一次 因为忘了最后ans可能小于0 还要在加上MOD

其实不用树状数组记录,就用数组就行了,每次内循环结束的时候,再遍历一下dp数组,算出下一次step的前缀和即可

代码:

31 int n, a, b, k;
32 ll dp[MAXN][MAXN];
33 
34 int main() {
35     cin >> n >> a >> b >> k;
36     dp[0][a] = 1;
37     rep(step, 0, k) {
38         rep(cnt, 1, n + 1) {
39             int l = max(1, cnt - abs((b - cnt)) + 1);
40             int r = min(n, cnt + abs((b - cnt)) - 1);
41             dp[step + 1][l] = (dp[step + 1][l] + dp[step][cnt]) % MOD;
42             dp[step + 1][cnt] = (dp[step + 1][cnt] - dp[step][cnt]) % MOD;
43             dp[step + 1][cnt + 1] = (dp[step + 1][cnt + 1] + dp[step][cnt]) % MOD;
44             dp[step + 1][r + 1] = (dp[step + 1][r + 1] - dp[step][cnt]) % MOD;
45         }
46         rep(cnt, 1, n + 1)
47             dp[step + 1][cnt] = (dp[step + 1][cnt] + dp[step + 1][cnt - 1]) % MOD;
48     }
49     ll ans = 0;
50     rep(i, 1, n + 1) ans = (ans + dp[k][i]) % MOD;
51     if (ans < 0) ans += MOD;
52     cout << ans << endl;
53     return 0;
54 }

 

posted @ 2017-08-04 17:41  Flowersea  阅读(137)  评论(0编辑  收藏  举报