CF_Round274_Div1C_Riding in a lift_动态规划
2014-10-20 00:54
411 查看
又过了十二点睡不了,让我早睡一次吧。
题意:
你在一个大楼里坐电梯玩,楼层从1到n编号,你一开始在a层,b层不能去,由于某些神秘的原因,你从x层可以到达的楼层y需要满足|x-y|<|x-b|,你一共要坐k次电梯,问有多少种做法?
Input
The first line of the input contains four space-separated integers
n, a,
b, k (2 ≤ n ≤ 5000,
1 ≤ k ≤ 5000, 1 ≤ a, b ≤ n,
a ≠ b).
Output
Print a single integer — the remainder after dividing the sought number of sequences by
1000000007 (109 + 7).
dp状态转移方程不难想,无非是从上一次乘坐可能的所有情况往这次推,dp数组记录当前点有多少种可能来源,但是k次加n层,已经需要O(NK)的时间复杂度了,单点递推不能满足效率要求,但是注意到可以递推的点是满足一个线性不等式,所以某个点的上一次乘坐地点肯定是线(扣掉了单个的点),那样就可以用前缀和的技巧,开一个数组记录从头到当前楼层每层dp值之和,而更新这个数组是和更新dp平行进行的,复杂度仍然是O(nk)。
具体递推公式不再赘述,解不等式即可。
比赛的时候已经写完了代码,但是递推公式的代码表述有点小问题,时间不够了没改完,今天主要是B题耗时太大。
代码如下:
题意:
你在一个大楼里坐电梯玩,楼层从1到n编号,你一开始在a层,b层不能去,由于某些神秘的原因,你从x层可以到达的楼层y需要满足|x-y|<|x-b|,你一共要坐k次电梯,问有多少种做法?
Input
The first line of the input contains four space-separated integers
n, a,
b, k (2 ≤ n ≤ 5000,
1 ≤ k ≤ 5000, 1 ≤ a, b ≤ n,
a ≠ b).
Output
Print a single integer — the remainder after dividing the sought number of sequences by
1000000007 (109 + 7).
dp状态转移方程不难想,无非是从上一次乘坐可能的所有情况往这次推,dp数组记录当前点有多少种可能来源,但是k次加n层,已经需要O(NK)的时间复杂度了,单点递推不能满足效率要求,但是注意到可以递推的点是满足一个线性不等式,所以某个点的上一次乘坐地点肯定是线(扣掉了单个的点),那样就可以用前缀和的技巧,开一个数组记录从头到当前楼层每层dp值之和,而更新这个数组是和更新dp平行进行的,复杂度仍然是O(nk)。
具体递推公式不再赘述,解不等式即可。
比赛的时候已经写完了代码,但是递推公式的代码表述有点小问题,时间不够了没改完,今天主要是B题耗时太大。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> using namespace std; #define mxn 5010 #define mod 1000000007 #define mxk 5010 long long dp[2][mxn]; long long sum[2][mxn]; int a,b,n,k; int main(){ while(scanf("%d%d%d%d",&n,&a,&b,&k)!=EOF){ memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); dp[0][a]=1; for(int i=a;i<=n;++i) sum[0][i]=1; for(int i=1;i<=k;++i) for(int j=1;j<=n;++j){ if(j<b){ int tem=(b+j)/2; if((b+j)%2==0) --tem; dp[i%2][j]=(sum[(i+1)%2][tem]-dp[(i+1)%2][j]+mod)%mod; } else if(j>b) dp[i%2][j]=(sum[(i+1)%2] -sum[(i+1)%2][(j+b)/2]-dp[(i+1)%2][j]+mod)%mod; sum[i%2][j]=(sum[i%2][j-1]+dp[i%2][j]+mod)%mod; } cout<<(sum[k%2] +mod)%mod<<endl; } return 0; }
相关文章推荐
- CF 274 div2 E - Riding in a Lift (递推)
- 【Codeforces Round 274 (Div 2)E】【DP 成段更新 打标记法 滚动数组】Riding in a Lift 乘坐k次电梯避免到达b层的方案数
- Codeforces Round #274 (Div. 2) Riding in a Lift(DP 前缀和)
- Codeforces Round #274 (Div. 2) E题:Riding in a Lift(DP)
- Codeforces Round #274 (Div. 2) E:Riding in a Lift DP + 前缀优化
- Codeforces Round #274 (Div. 2) E. Riding in a Lift(DP)
- Codeforces Round #274 (Div. 1) C. Riding in a Lift 前缀和优化dp
- Codeforces Round #274 Div.1 C Riding in a Lift --DP
- [笔记] Codeforces#274 Riding in a Lift (479E) DP
- CF479 Riding in a Lift
- Codeforces Round #274 (Div. 2) E. Riding in a Lift(DP)
- CF_Round274_Div1_B_Long Jump_二分搜索
- CF 479E Riding in a Lift 前缀和 DP
- Codeforces Round #274 (Div. 2) E. Riding in a Lift(DP)
- [CF480C]Riding in a Lift
- Codeforces Round #274 (Div. 1)——C. Riding in a Lift
- Codeforces Round #274 (Div. 2)-E. Riding in a Lift
- codeforce 479E - Riding in a Lift
- Codeforces Round #274 Riding in a Lift (DP)
- Codeforces Round #274 (Div. 2)E. Riding in a Lift