链接:
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 }