zoukankan      html  css  js  c++  java
  • #C++初学记录(动态规划 被3整除的子序列)

    原题:牛客网
    动态规划dynamic programming 的入门级题目
    题目描述 :
    给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
    答案对1e9+7取模
    输入描述:
    输入一个字符串,由数字构成,长度小于等于50
    输出描述:
    输出一个整数
    示例
    输入:

    132
    输出:
    3
    正确代码

    #include <bits/stdc++.h>
    using namespace std;
    const int Mod=1e9+7;
    int dp[3];
    char a1[55];
    int  main()
    {
    
        cin.getline(a1,55);
        memset(dp,0, sizeof(dp));
        int n=strlen(a1);
        for(int i=0;i<n;i++)
        {
            int s0=0,s1=0,s2=0;
            int x=a1[i]-'0';
            if(x%3==0){
                s0+=dp[0]+1;
                s1+=dp[1];
                s2+=dp[2];
            }
            if(x%3==1){
                s0+=dp[2];
                s1+=dp[0]+1;
                s2+=dp[1];
            }
            if(x%3==2){
                s0+=dp[1];
                s1+=dp[2];
                s2+=dp[0]+1;
            }
            dp[0]+=s0;
            dp[1]+=s1;
            dp[2]+=s2;
            for(int j=0;j<3;j++)
                dp[j]=dp[j]%Mod;
        }
        cout<<dp[0]<<endl;
    
    
    }
    
    

    题目认知:
    子序列与子串的区别在于连续与否,子串连续,子序列不连续,因此根据题意我们要对所有子序列进行判断是否满足题意和满足题意的子序列的个数有多少个,最后对结果取余数,取余数时,无论是最后一起取余,还是分步取余结果都是一样的,因此,分步取余更易于存储。
    对于如何对子序列进行判断
    就上文中的正确代码里,我使用了一个for循环对整个数组进行一次遍历,一次遍历即可求出所要结果。
    就dp思想而言,我们应该将大问题化为小问题,逐个对小问题进行求解,因此应该考虑如何分离子序列,然后再对子序列进行判断。

  • 相关阅读:
    编程范式 epesode7,8 stack存放指针类型and heap,register
    编程范式 episode 6 实现stack 栈功能_ to do
    C 运算符优先级
    编程范式 episode3 and 4,5
    编程范式 epesode2 negative values, float 精度
    C 数据类型 长度
    memcpy code
    排序算法 2 qsort 库函数,泛型函数
    sin, miss the mark, correct our aim and try again
    排序算法 1
  • 原文地址:https://www.cnblogs.com/xiaofengqaq/p/11302062.html
Copyright © 2011-2022 走看看