您的位置:首页 > 其它

NKOI 1008 核电站

2016-05-07 22:17 260 查看
核电站
Time Limit:3000MS  Memory Limit:65536K

Total Submit:153 Accepted:64
Description
一个核电站有N个放核物质的坑,坑排列在一条直线上。 如果连续M个坑中放入核物质(注:并不是总共只有M个核物质),则会发生爆炸,于是,在某些坑中可能不放核物质。

任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数

Input
一行,两个正整数N,M( 1<N≤60,2≤M≤10)

Output
每组数据只输出一个正整数S,表示方案总数。

Sample Input
4 3

Sample Output
13

Source

这是一道动规题,题意十分好理解,但是想起来却有些困难

我们可以用f[i]表示有i个坑的总方案数

由于m的值不确定,所以我们应首先讨论没有m的情况,即可以随便放的情况

当i==0时,只能选择不放,f[0]=1

当i==1时,可以放也可以不放,f[1]=2

当i==2时,第2个坑可以放也可不放,结合f[1]得到f[2]=f[1]+f[1]=4

当i==3时,第3个坑可以放也可以不放,结合f[2]得到f[3]=f[2]+f[2]=8

归纳可以得到规律f[i]=2*f[i-1]

据此可以讨论存在m的情况

当i<m时,m就相当于不存在,f[i]=2*f[i-1]

当i==m,原本全部都放的方案不可行了,所以要减去这种方案,f[i]=2*f[i-1]-1

当i>m,这也是本题最大的难点,首先先把此时的方程给出来f[i]=f[i-1]+f[i-1]-f[i-m-1]

这是显而易见的。两个f[i-1]分别代表的是f[i]位上放或者不放,也就是i<m的情况。但是f[i]上能放的条件是连续的一排上最多有m-1堆。以样例为例,当i=4时,可以知道:

如果在(4)放,在(3)号坑放的前提下(2)一定是不放的。所以要用在f[i-1](3号坑放的那一个)中排除有(2)且有(3)的那种情况。

由题意可知,如果(2)(3)都有核物质,(1)中一定没有。所以能达到图中的的状态的情况数只等于f[0],即f[i-m-1]的值。这时f[i-1]-f[i-m-1]就好理解了。

此时,问题就可以解决了,但是为了保险起见,f[]数组用了long long,事实证明是正确的

#include<iostream>

using namespace std;

long long f[70];

int main(){

    int n,m,i,j;

    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
;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: