上海金馬五校程序競賽網上資格賽 C Frog 【前綴和+DP】

本來這個題很簡單,但因爲做這種取膜的題太少,犯了很傻比的錯誤。在這裏mark一下

題面:

Description
There is a little frog called Matt. One day he comes to a river. The river could be considered as an axis. Matt is standing on the left bank now (at position 0). He wants to cross the river and reach the right bank (at position N). But Matt could only jump at most LL units, for example from 0 to L. There are N−1 rocks lying on the river equably (at position 1,2,⋯,N−1). The size of the rocks can be ignored, so each rock can be thought as a point on the axis. Matt can jump to a rock from the left bank or other rocks, and he can jump to the right bank from a rock or the left bank.
Now, Matt wants to know how many ways are there to cross the river. Of course, Matt could only jump forward.

Input
There are no more than 100 cases. Each case contains two integers N(2≤N≤100000)and L (1≤L≤N), denoting the position of the right bank and the distance Matt could jump most.

Output
For each test case, print the number of way to cross the river module 1e9+7.

Sample Input
3 1
4 3

Sample Output
1
7

題目大意:

有個數軸,長爲N,起始點爲0,每次最多可以移動L。問從0到N一共有多少種走法

大致思路:

可以通過簡單的例子推出一個狀態轉移方程:

dp[i]=dp[i1]+dp[i2]+....+dp[il]
但是,對於每一個 dp[i] 都進行這麼一個循環太過於浪費時間
所以引入一個 sum 數組,將前 i 個數字的總和統計,
然後就有 p[i]=sum[i]sum[il1]
最後掃一遍,答案就出來了
關鍵!!對於每次運算結果都取膜!!很重要!!!

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=1e5+10;
ll p[maxn];
ll sum[maxn];
int len,num;
int main()
{
    while(cin>>num>>len)
    {
        memset(p,0,sizeof(p));
        memset(sum,0,sizeof(sum));
        sum[0]=p[0]=p[1]=1;
        for(int i=1;i<=num;++i){
            p[i]=sum[i-1];
            if(i>len)
                p[i]=(p[i]-sum[i-len-1])%mod;
            sum[i]=(p[i]+sum[i-1])%mod;
            sum[i]%=mod;
        }
        cout<<(p[num]+mod)%mod<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章