zoukankan      html  css  js  c++  java
  • 1363: Count 101 (经典数位dp)

    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
    ",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的初始化
    
    其实还可以用斐波那契写,听学弟说的....
    
    */
  • 相关阅读:
    haproxy 2.5 发布
    cube.js sql 支持简单说明
    基于graalvm 开发一个cube.js jdbc driver 的思路
    apache kyuubi Frontend 支持mysql 协议
    oceanbase 资源池删除说明
    基于obd 的oceanbase 扩容说明
    jfilter一个方便的spring rest 响应过滤扩展
    cube.js schema 定义多datasource 说明
    typescript 编写自定义定义文件
    meow 辅助开发cli 应用的工具
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9487884.html
Copyright © 2011-2022 走看看