Given n floors, the first floor is in a. The second floor cannot be stayed. Select a floor X at a time. When | X-now | <| X-B | and X! = Now (now indicates the current position), records X to the sequence, takes K steps, and finally asks how many possible numbers there are.
Solution:
Definition: DP [I] [J] indicates the number of different sequences in step I on Building J.
Transfer equation: When j <B, then DP [I] [J] + = DP [I-1] [0 ~ (The midpoint of J and B (below)]
When J> B, then DP [I] [J] + = DP [I-1] [(the midpoint of J and B (below ))~ N]
Since the value of DP [I] [J] is only related to some values of DP [I-1] [], scrolling array greatly reduces memory.
Use a sum [I] [J] to maintain the prefix and.
Code:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#define Mod 1000000007#define lll __int64using namespace std;#define N 100007lll dp[2][5002],sum[2][5002];int n;int main(){ int a,b,k,i,j; while(cin>>n>>a>>b>>k) { memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); dp[0][a] = 1LL; for(i=a;i<=n;i++) sum[0][i] = 1LL; int now = 0; for(i=1;i<=k;i++) { now ^= 1; memset(dp[now],0,sizeof(dp[now])); memset(sum[now],0,sizeof(sum[now])); for(j=1;j<=n;j++) { if(j < b) { int k = (j+b-1)/2; dp[now][j] = (dp[now][j]+sum[now^1][k]-dp[now^1][j])%Mod; } else if(j > b) { int k = (j+b+2)/2; dp[now][j] = (dp[now][j]+sum[now^1][n]-sum[now^1][k-1]-dp[now^1][j])%Mod; } sum[now][j] = (sum[now][j-1]+dp[now][j])%Mod; } } lll sum = 0; for(i=1;i<=n;i++) sum = (sum+dp[now][i])%Mod; cout<<(sum+Mod)%Mod<<endl; } return 0;}
View code
Codeforces round #274 div.1 C riding in a lift -- DP