zoukankan      html  css  js  c++  java
  • 【数位DP】Hdu 3652:B-number

                        B-number

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3434    Accepted Submission(s): 1921

    Problem Description
    A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
     
    Input
    Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
     
    Output
    Print each answer in a single line.
     
    Sample Input
    13 100 200 1000
     
    Sample Output
    1 1 2 2 

      感觉拿到题目后没有什么思路。
      
      去%了一发题解。
      
      发现状态可以是多种多样的。
      
      设f[i][b][j][m]表示i位,第i位为j,b=0代表当前数字没有13,b=1相反,m代表%13等于m的所有数字的个数。
      
      在预处理里面直接加判一些东西,至于那个count函数指第i位为j的所有数字从之前%13=m的数字转移来的时候要加的mod数。
      
      说的再清楚一点就是以前mod 13=m,现在=(count(i,j)+m)%13
      
      其余的非法情况什么的再判一下咯。。
     
      
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstring>
     5 
     6 using namespace std;
     7 
     8 int f[16][2][16][16];
     9 
    10 int count(int x,int y)
    11 {
    12     for(int i=1;i<x;i++)
    13     y=y*10%13;
    14     return y;
    15 }
    16 
    17 void DP()
    18 {
    19     for(int i=0;i<=9;i++)
    20     f[1][0][i][i]=1;
    21     for(int i=2;i<=10;i++)
    22     for(int j=0;j<=9;j++)
    23     {
    24         int mod=count(i,j);
    25         for(int kk=0;kk<=9;kk++)
    26         for(int ll=0;ll<13;ll++)
    27         {
    28             if(j==1 && kk==3)f[i][1][j][ll]+=f[i-1][0][kk][(ll-mod+13)%13];
    29             else f[i][0][j][ll]+=f[i-1][0][kk][(ll-mod+13)%13];
    30             f[i][1][j][ll]+=f[i-1][1][kk][(ll-mod+13)%13];
    31         }
    32     }
    33 }
    34 
    35 int get(int x)
    36 {
    37     int num[12],len=0,res=0;
    38     while(x)
    39     {
    40     num[++len]=x%10;
    41     x/=10;
    42     }
    43     for(int i=1;i<num[len];i++)
    44     res+=f[len][1][i][0];
    45     for(int i=1;i<=len-1;i++)
    46     for(int j=1;j<=9;j++)
    47         res+=f[i][1][j][0];
    48     int mod=count(len,num[len]),flag=0;
    49     for(int i=len-1;i>=1;i--)
    50     {
    51     for(int j=0;j<num[i];j++)
    52     {
    53         res+=f[i][1][j][(13-mod)%13];
    54         if(flag || (j==3 && num[i+1]==1) )res+=f[i][0][j][(13-mod)%13];
    55     }
    56     if(num[i]==3&&num[i+1]==1)flag=1;
    57     mod=(mod+count(i,num[i]))%13;
    58     }
    59     return res;
    60 }
    61 
    62 int main()
    63 {
    64     int r;
    65     DP();
    66     while(~scanf("%d",&r))
    67     printf("%d
    ",get(r+1));
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    2020年北航OO助教工作总结
    OO第四单元——UML及其解析器——总结 暨 OO课程大总结
    OO第三单元——规格化设计与地铁系统——总结
    OO第二单元——电梯调度——总结
    OO第一单元——表达式求导——总结
    try_svg
    字体自适应
    网站使用微软雅黑需要版权吗
    body,td,th {
    input一定要在from里吗
  • 原文地址:https://www.cnblogs.com/tuigou/p/4832721.html
Copyright © 2011-2022 走看看