• HDU 3485【101】 51nod 1668【010】 joj 2171【111】动态规划


    有一个只含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
    
    */
    01字符串递推DP
    #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
    
    */
    dp[i][j]:长度i,j代表末尾0 or 1
  • 相关阅读:
    c/c++ 数组的智能指针 使用
    c/c++ 智能指针 weak_ptr 使用
    在ubuntu18.04上安装EOS
    c/c++ 智能指针 unique_ptr 使用
    python基础-内置装饰器classmethod和staticmethod
    java中5种异步转同步方法
    java自定义注解
    多线程之线程池(Thread,Runnable,callable,Future,FutureTask)
    java反射
    重写ThreadFactory方法和拒绝策略
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9489114.html
Copyright © 2020-2023  润新知