- Number of Ways to Stay in the Same Place After Some Steps
You have a pointer at index 0 in an array of size arrLen. At each step, you can move 1 position to the left, 1 position to the right in the array or stay in the same place (The pointer should not be placed outside the array at any time).
Given two integers steps and arrLen, return the number of ways such that your pointer still at index 0 after exactly steps steps.
Since the answer may be too large, return it modulo 10^9 + 7.
1.动态规划的数组设置参考官方题解,dp[i][j]表示走j步到达i有多少种方案。
转移关系:走j步到达i的方案有,j-1步时在i-1步,需要向右走;j-1步时在i+1步,需要向左走;j-1步时在i步,原地不动。所以dp[i][j]=dp[i-1][j-1]+dp[i][j-1]+dp[i+1][j-1].
细节:
- 计算结果可能很大,所以对每次的加法结果都要取模。由于运算只涉及加法,所以取模的位置为最终结果无影响
- 关于dp的size,arrlen>steps时,无法走到大于steps的部分,所以取dp的第一维为min(steps,arrlen)
int numWays(int steps, int arrLen) {
if(steps==1||arrLen==1){
return 1;
}
int n=arrLen;
if(n>steps){
n=steps;
}
vector<vector<int>>f;
f.resize(n,vector<int>(steps));
for(int i=0;i<n;i++){
f[i][i]=1;
}
for(int i=1;i<steps;i++){
f[0][i]=(f[0][i-1]+f[1][i-1])%(1000000007);
for(int j=1;i+j<steps&&j<n-1;j++){
f[j][i+j]=((f[j-1][i+j-1]+f[j][i+j-1])%(1000000007)+f[j+1][i+j-1])%(1000000007);
}
if(n-1+i<steps){
f[n-1][n-1+i]=(f[n-1][n-2+i]+f[n-2][n-2+i])%(1000000007);
}
}
return (f[0][steps-1]+f[1][steps-1])%(1000000007);
}
2.参考题解重写代码使更简洁
int numWays(int steps, int arrLen) {
if(steps==1||arrLen==1){
return 1;
}
int n=min(arrLen,steps);
vector<vector<int>>f;
f.resize(steps,vector<int>(n));
f[0][0]=1;
for(int i=1;i<steps;i++){
for(int j=0;j<=i&&j<n;j++){
f[i][j]=f[i-1][j];
if(j-1>=0){
f[i][j]=(f[i][j]+f[i-1][j-1])%(1000000007);
}
if(j+1<=i&&j+1<n){
f[i][j]=(f[i][j]+f[i-1][j+1])%(1000000007);
}
}
}
return (f[steps-1][0]+f[steps-1][1])%(1000000007);
}
3.官方题解
动态规划只涉及两行数据,所以可以只记录这两行
int numWays(int steps, int arrLen) {
if(steps==1||arrLen==1){
return 1;
}
int n=min(arrLen,steps);
vector<int>pre(n);
vector<int>cur(n);
pre[0]=1;
for(int i=1;i<steps;i++){
for(int j=0;j<=i&&j<n;j++){
cur[j]=pre[j];
if(j-1>=0){
cur[j]=(cur[j]+pre[j-1])%(1000000007);
}
if(j+1<=i&&j+1<n){
cur[j]=(cur[j]+pre[j+1])%(1000000007);
}
}
pre=cur;
}
return (cur[0]+cur[1])%(1000000007);
}