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

    题目传送门

    B-number

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


    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
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  3651 3655 3654 3653 3659 
    题意:求[1,n]中数位有13并且能被13整除的数
    题解:数位dp,状态就是要记录上一位,还要记录这个数,可开3维或者4维
    代码:
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef pair<int,int> PII;
    #define mod 1000000007
    #define pb push_back
    #define mp make_pair
    #define all(x) (x).begin(),(x).end()
    #define fi first
    #define se second
    //head
    int n;
    //int dp[10][2][13];
    int dp[10][10][2][13];//i:处理的数位,j:结尾的数 k:是否已经包含13 z:该数对13取模以后的值,
    int bit[10];
    int dfs(int  pos,int pre,bool flag,int sta,bool limit)
    {
        if(pos==-1)return sta%13==0&&flag;
        if(!limit&&dp[pos][pre][flag][sta%13]!=-1)return dp[pos][pre][flag][sta%13];
        int up=limit?bit[pos]:9;
        int ans=0;
        for(int i=0;i<=up;i++)
        {
            /*if(pre==2||pre==1&&i==3)
                ans+=dfs(pos-1,2,sta*10+i,limit&&i==up);
             else if(i==1)
               ans+=dfs(pos-1,1,sta*10+i,limit&&i==up);
             else
               ans+=dfs(pos-1,0,sta*10+i,limit&&i==up);*/
               ans+=dfs(pos-1,i,flag||(pre==1&&i==3),sta*10+i,limit&&i==up);
        }
        if(!limit)dp[pos][pre][flag][sta%13]=ans;
         return ans;
    }
    int calc(int x)
    {
        int len=0;
        while(x)
        {
            bit[len++]=x%10;
             x/=10;
        }
        return dfs(len-1,-1,0,0,1);
    }
    int main()
    {
        memset(dp,-1,sizeof(dp));
        while(~scanf("%d",&n))
        {
           printf("%d
    ",calc(n));
        }
        return 0;
    }
  • 相关阅读:
    二分图的最大匹配
    染色法判定二分图
    kruskal求最小生成树
    prim算法求最小生成树
    floyd
    spfa算法
    bellman_ford
    Dijkstra
    文件操作_1-18 选择题
    会话控制_2-5 编程练习
  • 原文地址:https://www.cnblogs.com/zhgyki/p/9756096.html
Copyright © 2011-2022 走看看