Detailed digit dp && LG P2602 [ZJOI2010] digital count

Digital dp, suitable for solving how many numbers or other compliance between x ~ y a class requirements.

example

Title Description

Hangzhou Transportation Authority will expand some of the regular taxi licenses, recently came up with a good news, after the license no longer contains an unlucky number, and this way, you can eliminate the psychological barriers to individual taxi drivers and passengers, and more safely serve the public.

Unlucky all numbers comprising 4 or 62. E.g:

62315 73418 88914

They belong unlucky number. However, while 61152 contains 6 and 2, but not even the number 62, it does not belong to the unlucky number of columns.

Your task is, for a license plate number each time interval given, infer Authority to pay this time how many cars have to actually give a new taxi vehicle licenses.

Input and output formats

Inputs are integers of A, B (0 <A≤B <10 ^ 9), if they are integers of 0, the input ends.

Scale data

20% of the data, to meet 1≤A≤B≤10 ^ 6;

100% of the data, to meet 1≤A≤B≤2 × 10 ^ 9.

solution

With solve(x)demand 0 ~ x in number to meet the requirements of a few; the answer is obviouslysolve(b)-solve(n-1)

So how do you solve it? (Do not use ordinary search and dp is also OK, but it will take a little) with the memory search

We consider the enumeration from low to high:

  • If all the bits are in front of "taking the top," and then the next one can only get from 0 to this bit: for example, took 43 4375 the first two, then the next one can only take 0 to this bit, which is 0 to 7

  • Otherwise, the next one may take 0-9

We use the flag to represent the first few there are no "take top"

F [l] [lst] represents the entire length l of a preceding number is the number of how many lst. Such as f [3] [5] is represented by the form 5 ___ ___ ___of the number of number (note: not shaped like 5 ___ ___!)

It should be noted that only in the case of flag = 0 to the memory of, because the flag = 0 when followed can take full; flag = take less than one back when, and the upper limit is uncertain.

See the specific implementation comments.

#include<bits/stdc++.h>
using namespace std;
    if(!flag&&f[l][lst]!=-1) return f[l][lst];//记忆化
    int u=flag?d[l]:9,anstmp=0;
    for(int i=0;i<=u;i++)
        if(i!=4&&!(lst==6&&i==2)) //这一位4或者前一位是6这一位是2(也就是组成62)是不行的。
            anstmp+=dfs(l-1,i,flag&&i==u);
    return flag?anstmp:f[l][lst]=anstmp;//只有flag=0时才能记忆化!
}
inline int solve(int k)
{
    cnt=0;
    while(k)
    {
        d[++cnt]=k%10;
        k/=10;
    }//先将当前的数一位一位拆开
    return dfs(cnt,0,1);
}
int main()
{
    memset(f,-1,sizeof(f));
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        if(n==m&&n==0) break;
        printf("%d\n",solve(m)-solve(n-1));
    }
    return 0;
}

P2602 [ZJOI2010] digital count

Title Description

Given two positive integers a and b, seeking in [a, b] of all integers, each digital (digit) each appeared many times.

Input Format

A line containing only two integers a, b, as described above meanings.

Output Format

Line 10 contains an integer, each represent 0 ~ 9 appears many times in the [a, b] in.

Scale data

30% of the data, 1≤a≤b≤10 ^ 6;

100% of the data, 1≤a≤b≤10 ^ 12.

achieve

ans [0 ~ 9] represents answer subject.

f [l] [lst] [11]: f [l] [lst] [0 ~ 9] each represents a number of 0 to 9, f [l] [lst] [10] represents a number of a few

f [l] [lst] [10] good operator, f [l] [lst] [0 ~ 9] considered not directly calculated, we take ans array before and after dfs dfs calculating the difference obtained by the method.

The dfs tstep with debugging, not the tube; dfs t in is a plus or minus, because the answer is 0 ~ m subtracting answers 0 ~ n-1, so that t = 1 when evaluated 0 ~ m, 0 ~ n-1 when t = -1

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,cnt=0,d[1005],f[1005][1005][11],k,b,ans[1005],bf[1005];
ll dfs(ll l,ll lst,bool flag,bool flagg,ll t,ll tstep)
{
    if(l==0) return 1;
    if(!flag&&!flagg&&f[l][lst][10]!=-1) 
    {
        for(ll i=0;i<=9;i++) ans[i]+=f[l][lst][i]*t;
        return f[l][lst][10];
    }
    ll u=(flag?d[l]:9),anstmp=0;
    for(int i=0;i<=9;i++) bf[i]=ans[i];
    for(ll i=0;i<=u;i++)
    {
        ll tttmp=dfs(l-1,i,flag&&i==u,flagg&&i==0,t,tstep+1);
        if(i!=0||!flagg)
        {
            ans[i]+=tttmp*t;
            anstmp+=tttmp;
        }
    }
    if(!flag&&!flagg) {for(int i=0;i<=9;i++) {f[l][lst][i]=abs(ans[i]-bf[i]);}}
    return (flag||flagg)?anstmp:f[l][lst][10]=anstmp;
}
inline ll solve(ll k,ll t)
{
    cnt=0;
    while(k)
    {
        d[++cnt]=k%10;
        k/=10;
    }
    return dfs(cnt,0,1,1,t,0);
}
int main()
{
    memset(f,-1,sizeof(f));
    scanf("%lld %lld",&n,&m);
    solve(m,1);
    solve(n-1,-1);
    for(ll i=0;i<=8;i++) printf("%lld ",ans[i]);
    printf("%lld",ans[9]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LJB00125/p/shuweidp-and-LG-P2602-tijie.html