分析:
就比如说这里有5个位置,间隔k=2,那么就有以下几种情况:
放一个桶:(1)、(2)、(3)、(4)、(5)
放两个桶:(1,4)、(1,5)、(2,5)
放三个桶:三个及以上放不下了。
那么,就有8中方案放桶了。
设置 dp[i] 表示以位置 i 结尾的方案总数。dp[1] = 1, dp[2] = 1,dp[4] = 2, dp[5] = 3…
因为,5-2-1=2>=1(i - k - 1),所以 dp[i] = 1,只用一种方案,因为要放更多的桶,那么我们就需要在左边有位置,如果小于1的话就表示没有位置了。
同时又因为n的范围是1e6,我们外循环遍历n个位置的时候,我们也要让dp[i]的数据变化,如果使用循环嵌套的话,那么就会超时。因此我们在计算和的时候,我们使用前缀和。
注意:
这将运行超时,使用前缀和优化。
for(int i=1;i<=n;i++){
dp[i]=0;
for(int j=max(0,i-k);j<i;j++){
dp[i]=(dp[i]+dp[j])%p;
}
}
cout<<dp[n]<<"\n";
示例代码:
#include<bits/stdc++.h>
using namespace std;
const int p = 1e9+7,N = 1e6+5;
int dp[N],prefix[N];
int main(){
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int n,k;cin>>n>>k;
dp[0]=prefix[0]=1;
for(int i=1;i<=n;i++){
if(i-k-1<1)dp[i]=1;
else dp[i]=prefix[i-k-1];
prefix[i]=(prefix[i-1]+dp[i])%p;
}
cout<<prefix[n]<<'\n';
return 0;
}