題目描述
一個核電站有N個放核物質的坑,坑排列在一條直線上。如果連續M個坑中放入核物質,則會發生爆炸,於是,在某些坑中可能不放核物質。
任務:對於給定的N和M,求不發生爆炸的放置核物質的方案總數
輸入格式
輸入文件只一行,兩個正整數N,M( 1<N<50,2≤M≤5)
輸出格式
輸出文件只有一個正整數S,表示方案總數。
題解:
一開始以為可以用數學方法解答,但WA了,看了別人的題解后有感。
設f[i]為第i個坑道使不爆炸的方案數。
當i<m時,f[i]=2*f[i-1];//因為第i個坑道只有放於不放2種情況
當i=m時,f[i]=2*f[i-1]-1;//減去的1是前m坑道都放的情況
當i>m時,f[i]=2*f[i-1]-f[i-m-1];//這是最難理解的部分,因為無論i-m-1的情況是什么,它后面都可以接i-m到m都是放的情況。或者說:當到第I個坑時,則第一個開始連着的坑其實是I-M+1,但是由於f[I-m]包括了第I-m個坑是“填”的情況,而這種情況下,已經出現了M+1個坑是連着“填”的情況,根據最優子結構,這種情況已經排除,因此我們只需要減去I-m個坑是“不填的情況”即f[I-m-1]
代碼實現:
#include<iostream> using namespace std; int main() { long long f[50];int i,n,m; cin>>n>>m; f[0]=1; for(i=1;i<=n;i++) { if(i<m) f[i]=2*f[i-1]; if(i==m) f[i]=2*f[i-1]-1; if(i>m) f[i]=2*f[i-1]-f[i-m-1]; } cout<<f[n]<<endl; return 0; }