1. 程式人生 > >1363: Count 101 (經典數位dp)

1363: Count 101 (經典數位dp)

gin fin algorithm 一個 滿足 col warning any iostream

1363: Count 101

Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 393 Solved: 154


Description

You know YaoYao is fond of his chains. He has a lot of chains and each chain has n diamonds on it. There are two kinds of diamonds, labeled 0 and 1. We can write down the label of diamonds on a chain. So each chain can be written as a sequence consisting of 0 and 1.

We know that chains are different with each other. And their length is exactly n. And what’s more, each chain sequence doesn’t contain “101” as a substring.
Could you tell how many chains will YaoYao have at most?

Input

There will be multiple test cases in a test data. For each test case, there is only one number n(n<10000). The end of the input is indicated by a -1, which should not be processed as a case.

Output

For each test case, only one line with a number indicating the total number of chains YaoYao can have at most of length n. The answer should be print after module 9997.

Sample Input

3
4
-1

Sample Output

7
12

Hint

We can see when the length equals to 4. We can have those chains:

0000,0001,0010,0011
0100,0110,0111,1000
1001,1100,1110,1111

給你長度為n的序列,只能由0或者1組成
不能出現101,問你這樣序列的個數 分析:
數位dp
可以由很多dp方式,比如三維dp
做過一個非常類似的題
dp1[i]:表示長度為i的滿足要求的(不出現101)的以0結尾的方案數
dp2[i]:表示長度為i的滿足要求的(不出現101)的以1結尾的方案數目
dp3[i]:表示長度為i的滿足要求的以(1或者0)結尾的方案數目 dp3[i]=dp1[i]+dp2[i]; 所以我們只需要得的dp1和dp2的轉移方程
dp1:
想一下dp1[i]的含義(以0結尾)
因為題目要求是沒有101
所以對dp1,第i位置
前面的第i-1位置可以是0,可以是1
所以:dp1[i]=dp1[i-1]+dp2[i-1] dp2:
想一下dp2[i]的含義(以1結尾)
題目要求沒有101
對dp2的第i位置
所以肯定第i位置肯定是1(dp2的含義)
所以前面的第i-1個位置也只能是1
前面的第i-2個位置也只能是0
這樣才不會有101出現
所以:
dp2[i]=dp2[i-1]+dp1[i-2] 所以通過dp1和dp2,我們就可以知道dp3了 註意:記得dp的初始化 其實還可以用斐波那契寫,聽學弟說的....
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<memory.h>
#include<memory>
using namespace std;
#define max_v 10005
#define mod 9997
int dp1[max_v];
int dp2[max_v];
int dp3[max_v];
int main()
{
    dp1[1]=1;
    dp1[2]=2;

    dp2[1]=1;
    dp2[2]=2;

    dp3[1]=dp1[1]+dp2[1];
    dp3[2]=dp1[2]+dp2[2];
    for(int i=3;i<10000;i++)
    {
        dp1[i]=(dp1[i-1]+dp2[i-1])%mod;
        dp2[i]=(dp1[i-2]+dp2[i-1])%mod;
        dp3[i]=(dp1[i]+dp2[i])%mod;
    }

    int n;
    while(~scanf("%d",&n))
    {
        if(n<0)
            break;
        printf("%d\n",dp3[n]);
    }
    return 0;
}
/*
給你長度為n的序列,只能由0或者1組成
不能出現101,問你這樣序列的個數

分析:
數位dp
可以由很多dp方式,比如三維dp
做過一個非常類似的題
dp1[i]:表示長度為i的滿足要求的(不出現101)的以0結尾的方案數
dp2[i]:表示長度為i的滿足要求的(不出現101)的以1結尾的方案數目
dp3[i]:表示長度為i的滿足要求的以(1或者0)結尾的方案數目

dp3[i]=dp1[i]+dp2[i];

所以我們只需要得的dp1和dp2的轉移方程
dp1:
想一下dp1[i]的含義(以0結尾)
因為題目要求是沒有101
所以對dp1,第i位置
前面的第i-1位置可以是0,可以是1
所以:dp1[i]=dp1[i-1]+dp2[i-1]

dp2:
想一下dp2[i]的含義(以1結尾)
題目要求沒有101
對dp2的第i位置
所以肯定第i位置肯定是1(dp2的含義)
所以前面的第i-1個位置也只能是1
前面的第i-2個位置也只能是0
這樣才不會有101出現
所以:
dp2[i]=dp2[i-1]+dp1[i-2]

所以通過dp1和dp2,我們就可以知道dp3了

註意:記得dp的初始化

其實還可以用斐波那契寫,聽學弟說的....

*/

1363: Count 101 (經典數位dp)