有一个只含0和1的长度为n的串,问不含有101的所有串的个数。
——不存在连续的101、010、111的字符串数量
HDU:https://cn.vjudge.net/problem/HDU-3485
51nod:
https://blog.csdn.net/Viscu/article/details/52669071
https://blog.csdn.net/lwlldd/article/details/70941554
https://blog.csdn.net/xtulollipop/article/details/52689159
https://blog.csdn.net/f_zyj/article/details/52663012
https://blog.csdn.net/LuRiCheng/article/details/52673193
JOJ:https://blog.csdn.net/kongming_acm/article/details/5377198
https://blog.csdn.net/jcwkyl/article/details/4153057
http://blog.sina.com.cn/s/blog_944759ba0100vmz9.html
记录后两位,共有4种情况
00->0
01->1
10->2
11->3;
【101的时候】
dp[i][0]=dp[i-1][0]+dp[i-1][2];
dp[i][1]=dp[i-1][0];
dp[i][2]=dp[i-1][1]+dp[i-1][3];
dp[i][3]=dp[i-1][1]+dp[i-1][3];
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define debug() puts("++++") #define gcd(a,b) __gcd(a,b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a,b,sizeof(a)) #define sz size() #define be begin() #define mp make_pair #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define rep(i,x,n) for(int i=(x); i<=(n); i++) #define in freopen("in.in","r",stdin) #define out freopen("out.out","w",stdout) #define mod 9997 using namespace std; typedef long long ll; typedef unsigned long long ULL; typedef pair<int,int> P; const ULL base = 100000007;//33951943 const int INF = 0x3f3f3f3f; const ll LNF = 9997; const int maxn = 10000+20; const int maxm = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-8; const int dx[] = {-1,1,0,0,1,1,-1,-1}; const int dy[] = {0,0,1,-1,1,-1,1,-1}; int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* 010 00 - 0 01 - 1 10 - 2 11 - 3 */ ll dp[maxn][4],ans[maxn]; void init() { //111 ms(dp,0); dp[1][0]=2; dp[2][0]=1;dp[2][1]=1;dp[2][2]=1;dp[2][3]=1; for(int i=3;i<10000;i++) { dp[i][0]=(dp[i-1][0]+dp[i-1][2])%mod; dp[i][1]=(dp[i-1][0]+dp[i-1][2])%mod; dp[i][2]=(dp[i-1][1]+dp[i-1][3])%mod; dp[i][3]=(dp[i-1][1])%mod; } } void init1() { //101 ms(dp,0); dp[1][0]=2; dp[2][0]=1;dp[2][1]=1;dp[2][2]=1;dp[2][3]=1; for(int i=3;i<10000;i++) { dp[i][0]=(dp[i-1][0]+dp[i-1][2])%mod; dp[i][1]=(dp[i-1][0])%mod; dp[i][2]=(dp[i-1][1]+dp[i-1][3])%mod; dp[i][3]=(dp[i-1][1]+dp[i-1][3])%mod; } } void init2() { //010 ms(dp,0); dp[1][0]=2; dp[2][0]=1;dp[2][1]=1;dp[2][2]=1;dp[2][3]=1; for(int i=3;i<10000;i++) { dp[i][0]=(dp[i-1][0]+dp[i-1][2])%mod; dp[i][1]=(dp[i-1][0]+dp[i-1][2])%mod; dp[i][2]=(dp[i-1][3])%mod; dp[i][3]=(dp[i-1][1]+dp[i-1][3])%mod; } } int main() { int n; while(cin>>n) { init(); if(n==-1) break; cout<<(dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3])%mod<<endl; } } /* 【题意】 【类型】 【分析】 【时间复杂度&&优化】 【trick】 首先dp打表找个规律: 如何DP? 这里我们找合法串:010 假设末尾i是1,那么i-1位置上无论是0和还是1都合法,不会出现010的情况,那么 就是dp[i][1] = dp[i-1][0] + dp[i-1][1]; 如果末尾i是0, 如果i-1位置上是0,那么无论如何也是合法的, 如果i-1的位置上是1,会出现010/101这样的情况,那么讨论第i-2位上的,i-2如果是0,那么会出现010的情况, 如果i-2位置上是1的话,无论如何都是合法串,那就是dp[i][0] = dp[i-1][0] + dp[i-2][1]; 【数据】 0 1(i-3)-0 00 01 10 11(i-2)x1 000 001 【010/1】 011 100 【110/1】 111 (i-1) x10 010-1 110-1 */
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define debug() puts("++++") #define gcd(a,b) __gcd(a,b) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define fi first #define se second #define pb push_back #define sqr(x) ((x)*(x)) #define ms(a,b) memset(a,b,sizeof(a)) #define sz size() #define be begin() #define mp make_pair #define pu push_up #define pd push_down #define cl clear() #define lowbit(x) -x&x #define all 1,n,1 #define rep(i,x,n) for(int i=(x); i<=(n); i++) #define in freopen("in.in","r",stdin) #define out freopen("out.out","w",stdout) #define mod 9997 using namespace std; typedef long long ll; typedef unsigned long long ULL; typedef pair<int,int> P; const ULL base = 100000007;//33951943 const int INF = 0x3f3f3f3f; const ll LNF = 9997; const int maxn = 10000+20; const int maxm = 1e6 + 10; const double PI = acos(-1.0); const double eps = 1e-8; const int dx[] = {-1,1,0,0,1,1,-1,-1}; const int dy[] = {0,0,1,-1,1,-1,1,-1}; int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}}; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* 0 001 0 1 00 01 10 11 0 2 4 7 */ ll dp[maxn][2],ans[maxn]; void init() { ms(dp,0); ms(ans,0); ans[0]=0;ans[1]=2;ans[2]=4; dp[1][0]=1,dp[1][1]=1; dp[2][0]=2,dp[2][1]=2; //dp[3][0]=4;dp[3][1]=3; for(int i=3;i<10000;i++) { dp[i][0]=(dp[i-1][0]+dp[i-1][1])%mod; dp[i][1]=(dp[i-1][1]+dp[i-2][0])%mod; ans[i]=(dp[i][0]%mod+dp[i][1]%mod)%mod; } } int main() { int n; while(cin>>n) { init(); if(n==-1) break; cout<<ans[n]%mod<<endl; } } /* 【题意】 【类型】 【分析】 【时间复杂度&&优化】 【trick】 首先dp打表找个规律: 如何DP? 这里我们找合法串:010 假设末尾i是1,那么i-1位置上无论是0和还是1都合法,不会出现010的情况,那么 就是dp[i][1] = dp[i-1][0] + dp[i-1][1]; 如果末尾i是0, 如果i-1位置上是0,那么无论如何也是合法的, 如果i-1的位置上是1,会出现010/101这样的情况,那么讨论第i-2位上的,i-2如果是0,那么会出现010的情况, 如果i-2位置上是1的话,无论如何都是合法串,那就是dp[i][0] = dp[i-1][0] + dp[i-2][1]; 【数据】 0 1(i-3)-0 00 01 10 11(i-2)x1 000 001 【010/1】 011 100 【110/1】 111 (i-1) x10 010-1 110-1 */