中石油 : 炸弹安放

时间限制: 1 Sec 内存限制: 128 MB

题目描述

小蔡决定在小头家门口安放炸弹!!
小头家门口有n个连续的格子排成一行,对于每个格子,小蔡可以决定放一颗炸弹或者不放。为了防止小头被炸死,小蔡不会在连续3个格子都放上炸弹。小蔡想知道一共有多少安放炸弹的方案(可以一个也不放)。
由于方案数可能很多,所以你只需要方案个数mod 55555就可以了。

输入

一个正整数,即n(n≤1000)

输出

仅包含一个整数,即答案

样例输入

4

样例输出

13

提示

对于样例1的解释,一共有4个格子,每个格子可以选择放或者不放,因此根据乘法原理共有222*2=16种方案,其中在(1,2,3)上放炸弹是不合法的,会炸死小头。同样(2,3,4)和(1,2,3,4)也都不合法,所以一共有16-3=13种方案
13 mod 55555=13,因此答案为13

思路

设dp [ i ] [ j ] [ k ] ,表示到第 i 位时,i-1位状态为 j,i 位状态为 k 的答案,j 和 k 的取值为0和1代表放和不放。然后就是根据不能有三个连在一起的考虑:
dp [ i ] [ 0 ] [ 0 ] 就由 dp [ i-1 ] [ 0 ] [ 0 ] 和 dp [ i-1 ] [ 1 ] [ 0 ]转移过来
同理求剩下的 01 , 10 , 11 转移方程
最后答案就是n位的四个状态的答案加起来

dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
dp[i][0][1]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;
dp[i][1][1]=dp[i-1][0][1]%mod;

嗯,,,这个题我做的时候卡住了,是请教了师傅才做出来的,,唉,,自己还是太菜了,我什么时候才能像师傅一样强啊/(ㄒoㄒ)/~~
代码:

#include
#include
using namespace std;
const int mod=55555;
int n,ans,dp[1010][2][2];
int main( )
{
    cin>>n;
    dp[2][0][0]=1;
    dp[2][0][1]=1;
    dp[2][1][0]=1;
    dp[2][1][1]=1;
    for(int i=3;i<=n;i++)
    {
        dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
        dp[i][0][1]=(dp[i-1][1][0]+dp[i-1][0][0])%mod;
        dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%mod;
        dp[i][1][1]=dp[i-1][0][1]%mod;
    }
    ans=dp[n][0][0]+dp[n][0][1]+dp[n][1][0]+dp[n][1][1];
    cout<<ans%mod;
    return 0;
}

你可能感兴趣的:(dp,动态规划)