Codeforces 479E Riding in a Lift (DP)

来源:互联网 发布:centos 6.5 硬盘分区 编辑:程序博客网 时间:2024/06/01 10:31

题意:有n层楼,你现在在a层,禁地在b层,每次的移动如下:从x层移动到y层,必须满足|x-y|<|x-b|。问移动恰好k次的方案数。

解析:设dp[i][j]为移动了i次位于j层的方案数。则对于dp[i-1][j],

dp[i][每个从j层可以移动到的位置] += dp[i-1][j]。

采用类似BIT区间增减的方法标记对应的端点,进行状态转移。

[code]:

#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<set>using namespace std;typedef long long LL;const LL MOD = 1e9+7;const int maxn = 5005;int n,a,b,k;LL dp[maxn],S[maxn];int main(){    int i,j,t;    scanf("%d%d%d%d",&n,&a,&b,&k);    memset(dp,0,sizeof(dp));    dp[a] = 1;    memset(S,0,sizeof(S));    for(i = 1;i <= k;i++){        for(j = 1;j <= n;j++){            if(j < b){                S[b] = ((S[b]-dp[j])%MOD+MOD)%MOD;                S[j] = ((S[j]-dp[j])%MOD+MOD)%MOD;                t = max(1,2*j-b+1);                S[t] = (S[t]+dp[j])%MOD;                S[j+1]  = (S[j+1]+dp[j])%MOD;            }else{                S[b+1] = (S[b+1]+dp[j])%MOD;                S[j+1] = (S[j+1]+dp[j])%MOD;                S[j] = ((S[j]-dp[j])%MOD+MOD)%MOD;                t = min(n+1,2*j-b);                S[t] = ((S[t]-dp[j])%MOD+MOD)%MOD;            }        }        LL sum = 0;        for(j = 1;j <= n;j++){            sum = (sum+S[j])%MOD;            dp[j] = sum;            S[j] = 0;        }    }    LL ans = 0;    for(j = 1;j <= n;j++) ans = (ans + dp[j])%MOD;    printf("%I64d\n",ans);    return 0;}


0 0
原创粉丝点击