zoukankan      html  css  js  c++  java
  • hdu3652B-number (数位dp)

    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
     

    Author
    wqb0039
     


    题意:给你一个数n,让你求1~n中有多少数x符合x%13==0 且x中出现过“13”这个子串。

    思路:用dfs(pre,pos,num,flag,limit)来数出所有符合条件的数,其中pre表示这一位的上一位是什么,pos表示当前正循环到哪个位置,num表示到这一位时的总和(%13后,且这一位还没有算),flag表示之前的字符串中是否已经出现过"13"这个字符串,limit表示当前这位是有限制还是没有限制的,有限制的话,这一位最高遍历到wei[pos],没有限制的话最高遍历到9.另外没有剪枝的话会超时,所以用dp[pre][pos][num][flag]表示在limit==0的情况下,后面可以加上的值,如果(pre,pos,flag)这个状态已经遍历过的话,就不用遍历一遍了。


    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef long double ldb;
    #define inf 99999999
    #define pi acos(-1.0)
    #define maxn 805
    int wei[15];
    int dp[11][40][15][2];//到i位置%13为j且是否含有13的flag值为k的方案数
    
    int dfs(int pre,int pos,int num,int flag,int limit){
        int i,j;
        if(pos==0){
            if((num%13==0) && (flag==1))return 1;
            return 0;
        }
        if((limit==0) && (dp[pre][pos][num][flag]!=-1) ){
            return dp[pre][pos][num][flag];
        }
    
        int sum=0;
        int num1,flag1;
    
        if(limit==0){
            for(j=0;j<=9;j++){
                num1=(num*10+j)%13;
                flag1=flag;
                if((pre==1) && (j==3) ){
                    flag1=1;
                }
                sum+=dfs(j,pos-1,num1,flag1,0);
            }
        }
        else if(limit==1){
            for(j=0;j<=wei[pos];j++){
                num1=(num*10+j)%13;
                flag1=flag;
                if((pre==1) && (j==3) ){
                    flag1=1;
                }
                if(j<wei[pos])sum+=dfs(j,pos-1,num1,flag1,0);
                else sum+=dfs(j,pos-1,num1,flag1,1);
            }
        }
    
        if(limit==0){
            dp[pre][pos][num][flag]=sum;
        }
        return sum;
    }
    int solve(int x)
    {
        int i,j,len=0,t=x;
        while(t){
            wei[++len]=t%10;
            t/=10;
        }
        wei[len+1]=0;
        memset(dp,-1,sizeof(dp));
        int sum;
        sum=dfs(0,len,0,0,1);
        return sum;
    }
    
    
    int main()
    {
        int n,m,i,j;
        while(scanf("%d",&n)!=EOF)
        {
            printf("%d
    ",solve(n));
        }
    }
    


  • 相关阅读:
    剑指offer55. 平衡二叉树
    剑指offer52. 两个链表的第一个公共节点
    LC1043. Partition Array for Maximum Sum
    剑指offer40. Top K
    剑指offer39. 数组中出现次数超过一半的数字
    剑指offer36.将BST原地转换为双向循环链表
    判断大小端
    CentOS安装RabbitMQ 3.8.9
    Nginx 413 Request Too Large 错误
    NginxPC端和移动端区分
  • 原文地址:https://www.cnblogs.com/herumw/p/9464530.html
Copyright © 2011-2022 走看看