zoukankan      html  css  js  c++  java
  • hdu3652 B-number 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3652

    题意就是求区间内能被13整除并且包含”13“的数字的个数

    感觉是比较中等的数位DP题目

    我用的记忆化的方式做的

    定义dp[len][mod][mark];

    其中len表示当前正在处理的位数或可以理解为还有len位需要处理,mod表示当前的总的余数(即从最高位到len位时所计算得到的余数)

    mark起标记作用

    mark==0表示从最高位到i位还没有出现”13“;

    mak==1表示从最高位到i位没有出现”13“,但第i位为1

    mark==2表示从最高位到i位包含”13“

    具体实现如下:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 int n;
     7 int len;
     8 int bit[40];
     9 int dp[40][14][4];
    10 
    11 void init(int n)
    12 {
    13       memset(dp,-1,sizeof(dp));
    14      len=0;
    15     while(n)
    16     {
    17        bit[++len]=n%10;
    18        n/=10;
    19     }
    20 
    21 }
    22 int dfs(int len,int mod,int mark,int flag)
    23 {
    24    int sum=0;
    25    if(len==0) return  mod==0 && mark==2;
    26    if(flag && dp[len][mod][mark]>=0) return dp[len][mod][mark];
    27    int tmp=flag?9:bit[len];
    28 
    29    for(int i=0;i<=tmp;i++)
    30    {
    31       int Mod=(mod*10+i)%13;
    32 
    33       int Mark=mark;
    34       if(mark!=2 && i!=1) Mark=0;
    35       if(mark!=2 && i==1) Mark=1;
    36       if(mark==1 && i==3 )Mark=2;
    37       sum+=dfs(len-1,Mod,Mark,flag||i<tmp);
    38    }
    39    if(flag) dp[len][mod][mark]=sum;
    40    return sum;
    41 
    42 }
    43 int main()
    44 {
    45    while(scanf("%d",&n)!=EOF)
    46    {
    47       init(n);
    48       cout<<dfs(len,0,0,0)<<endl;
    49    }
    50    return 0;
    51 }
  • 相关阅读:
    容器小结
    STL之Map和multimap容器
    STL之Set和multiset容器
    STL之优先级队列priority_queue
    STL之List容器
    STL之Queue容器
    STL之stack容器
    应用安全-提权/降权相关整理
    安卓监听工具整理
    Linux命令整理-Kali
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu3652.html
Copyright © 2011-2022 走看看