问题描述
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?
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?
输入
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.
输出
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.
样例输入
3 4 -1
样例输出
7 12
提示
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 01串去掉101串的个数; 可以用dp[i]表示长度为i时的最多个数; 算dp[i]时,因为首位相比i-1新加了一个1,所以就应该是dp[i-1]*2,但是因为多加了以为所以前面三尾可能出现101的情况 ,所以这个时候还要减去这种情况的个数,这种情况就是第i-1位是0,i-2位是1,即第i-1位取0的个数减去第i-2位取0的个数(这里需要思考一下) 所以就是dp[i-2]-dp[i-3]; 所以状态转移方程为dp[i]=dp[i-1]*2-(dp[i-2]-dp[i-3]); 代码如下:#include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> #include <iomanip> #include <math.h> using namespace std; int dp[10005]; int main() { dp[1]=2;dp[2]=4;dp[3]=7; for(int i=4;i<=10005;i++) dp[i]=(2*dp[i-1]-(dp[i-2]-dp[i-3]))%9997; int n; while(cin>>n,n!=-1) cout<<dp[n]<<endl; }