zoukankan      html  css  js  c++  java
  • 动态规划-被3整除的子序列

    题目描述

    给你一个长度为50的数字串,问你有多少个子序列构成的数字可以被3整除
    答案对1e9+7取模

    输入描述:

    输入一个字符串,由数字构成,长度小于等于50

    输出描述:

    输出一个整数
    示例1

    输入

    132

    输出

    3
    示例2

    输入

    9

    输出

    1
    示例3

    输入

    333

    输出

    7
    示例4

    输入

    123456

    输出

    23
    示例5

    输入

    00

    输出

    3

    思路:

    把字符串每个数字取模3 处理成 只有0 1 2三个字符的串。

    二维数组dp[i] [j] 表示 前 i 个长度的所有子序列数位数字和取模 3 为 j 的数目( 0 <= j <= 2)

    有状态转移方程 :dp[i] [j] = (dp[i - 1] [j] + dp[i - 1] [ (3 + j - m) % 3]) % 1000000007;

    表示dp[i] [j]可以由两种情况递推过来:

    1.  第 i 个数字不用, 直接继承 dp[i - 1] [j]。

    2. 第 i 个数字与前边的一些数位和为 ( 3 +  j - m) % 3 的所有子序列相接。

    最后这个数字自己构成长度为 1 的子序列单独加上。

    代码:

     1 #include <cstdio>
     2 #include <fstream>
     3 #include <algorithm>
     4 #include <cmath>
     5 #include <deque>
     6 #include <vector>
     7 #include <queue>
     8 #include <string>
     9 #include <cstring>
    10 #include <map>
    11 #include <stack>
    12 #include <set>
    13 #include <sstream>
    14 #include <iostream>
    15 #define mod 1000000007
    16 #define eps 1e-6
    17 #define ll long long
    18 #define INF 0x3f3f3f3f
    19 using namespace std;
    20 
    21 string str;
    22 int dp[55][55];
    23 int main()
    24 {
    25     cin>>str;
    26     dp[1][(str[0]-'0')%3]=1;
    27     int s=str.length();
    28     for(int i=2;i<=s;i++)
    29     {
    30         int x=(str[i-1]-'0')%3;
    31         for(int j=0;j<=2;j++)
    32         {
    33             dp[i][j]=(dp[i-1][j]+dp[i-1][(3+j-x)%3])%mod;
    34         }
    35         dp[i][x]=(dp[i][x]+1)%mod;
    36     }
    37     printf("%d
    ",dp[s][0]%mod);
    38 }
  • 相关阅读:
    POJ1806 Manhattan 2025
    POJ1258 AgriNet【最小生成树】
    POJ1789 Truck History【最小生成树】【终于AC了】
    memset的用法
    HDOJ1106 排序
    POJ2965
    414某OJ竞赛题
    HDOJ1745 I hate it【线段树】
    HDOJ2795 Billboard【线段树】
    蓝桥杯o(︶︿︶)o 唉
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11388153.html
Copyright © 2011-2022 走看看