单点时限: 2.0 sec
内存限制: 256 MB
一个核电站有 N 个放核物质的坑,坑排列在一条直线上。
如果连续 M 个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的 N 和 M,求不发生爆炸的放置核物质的方案总数
输入格式
该题有多组测试数据,每组数据一行,两个正整数 N,M( 1<N≤50,2≤M≤5)
输出格式
每组数据只输出一个正整数 S,表示方案总数。
样例
input
4 3
output
13
此题与2846. 统计字符串个数差不多
/*
思路一:dfs每次都有两种状态,放与不放,放时个数加一,到放到的数量满足m个数就return,当递归到n时方案数加一。不过超时了。
*/
#include<iostream>
#include<cmath>
using namespace std;
int n,m;
long long ans=0;
void dfs(int i,int j) {
if(j==m)
return;
if(i==n) {
ans++;
return;
}
dfs(i+1,0);
dfs(i+1,j+1);
}
int main() {
while(cin>>n>>m) {
ans=0;
dfs(0,0);
cout<<ans<<endl;
}
}
/*
思路:
令 F(n) 表示前 n 个坑,不发生爆炸的放置核物质的方案总数。
当 n>m 时,对于第 n 个坑而言,有以下两种情况:
不放核物质,有 F(n−1) 种方案放核物质
放时,那么前 n−1 个坑中,最后 m−1 个坑不能有核物质,这等价于n-1个坑中最后m-1个坑不能全为核物质。即F[N-1]减去后面m-1全为核物质的方案数。即后面全为m-1核物质的方案数就是F[n-m-1]。所以,这种情况下,有 F(n−1)−F(n−m−1) 种方案。
综上所述,当 n>m 时 F(n)=2×F(n−1)−F(n−m−1)
当 n<m 时,不管怎么放都不会爆炸,F(n)=2xF[n-1]
当 n=M 时,F(n)=2×F(n−1)−1
*/
#include<iostream>
#include<cmath>
using namespace std;
int n,m;
void f() {
long long dp[n+1];
dp[0]=1;
for(int i = 1; i <= n; i++) {
if(i<m)
dp[i]=dp[i-1]*2;
else if(i==m)
dp[i]=2*dp[i-1]-1;
else {
dp[i]=2*dp[i-1]-dp[i-m-1];
}
}
cout<<dp[n]<<endl;
}
int main() {
while(cin>>n>>m) {
f();
}
}