题目描述
假设有排成一行的N个位置,记为1~N,开始时机器人在M位置,机器人可以往左或者往右走,如果机器人在1位置,那么下一步机器人只能走到2位置,如果机器人在N位置,那么下一步机器人只能走到N-1位置。规定机器人只能走k步,最终能来到P位置的方法有多少种。由于方案数可能比较大,所以答案需要对1e9+7取模。
输入
5 2 3 3
输出
3
说明
1).2->1,1->2,2->3 2).2->3,3->2,2->3 3).2->3,3->4,4->3
对于这个问题,其与子问题的关系为:
走k步到达arr[i]位置的总方案数目:
=走k-1步到达arr[i-1]位置的方案数+走k-1步到达arr[i+1]位置的方案数
因此该问题的解决思路为:从k=1步开始,研究走k步到达arr[]位置的方案数,那么下一次计算k+1时,直接利用k次计算结果
技巧点:
由于1位置左边没有元素,N位置右边没有元素=》那么首尾0和N+1位置:设置为0 计算1=>N
第k步计算利用k-1步计算结果,但不能采取逆序滚动数组,因为这里使用前后两个元素=>使用cur[]last[]数组
代码:
int main()
{
int N,M,K,P;
cin>>N>>M>>K>>P;
vector<int> last(N+2,0);
vector<int> cur(N+2,0);//滚动数组
last[M]=1;//当一步都不走时,初始位置[M]=1
//迭代计算 每次步数 step+1 cur[i]即 走step步到达i位置的方案数量
//cur[i]=last[i-1]+last[i+1] 即:走step-1步到达其左右的数量
for(int step=1;step<=K;step++)
{
for(int i=1;i<=N;i++)
cur[i]=(last[i-1]+last[i+1])%mod;
for(int i=1;i<=N;i++)
last[i]=cur[i];//记录下last 下一次使用
}
cout<<cur[P]<<endl;
}