Delete [T2988 digital pressure Dp + prefix and shape optimization]

Judge Online : moved here from Topcoder,Which specific question is not clear

The Label : prefixes and shape optimization pressure Dp +

Title Description

Given two numbers A and N, to form a sequence of length N + 1 is, (A, A + 1, A + 2, ..., A + N-1, A + N).

Each operation can be x-digit number on the i deleted, a new digital form.

Each number can be operated any number of times, but you can not delete all finished.

Seeking how many programs, such that the final numbers are monotonically decreasing sequence.

Two programs that are different, if the i-th bit of x is deleted in one embodiment, in another embodiment, not deleted.

Tip: Note that a number can not delete all the bits are all light, must have at least one still preserved. In addition, if the numbers (100 \) \ delete to \ (00 \) or \ (0 \) , they said the value is 0, but the two programs are considered different.

Entry

Input two integers A and N

Export

Output program number, remainder of 1e9 + 7.

Sample

Input#1

10 2

Output#1

15

Input#2

111 11

Output#2

184432

Hint

For 30% of the data, range A [ \ (1, 100 \) ], the range of N [ \ (1, 10 \) ];
for 70% of data, range A [ \ (9, 10 ^ \) ] ;
100% of the data range a [ (12 1, 10 ^ {} \) \ scope] a N [ \ (1, 100 \) ];

answer

Title to the surface is a gradual rise of a continuous sequence of integers, started to think what is the nature of the practice but in the end it seems like the pressure dp, so we do as a normal sequence on the line, the TC may enter too many questions Convenience? ? .

30pts

For 30% of the data, because the small range of n, the number of digits is not much direct violence can enumerate each number which bits deleted.

A first pre-array \ (SUM [i] [STA] \) , the i-th bit represents the status of \ (STA \) value (binary 0 indicates deleted, 1 expressed reservations). For example the i-th digit is 123, \ ([i] SUM [. 3 (. 11)] = 23 is \) , \ ([i] SUM [. 7 (111)] = 123 \) .

Realization enumerates with dfs. The total time complexity is \ (O (2 ^ {}} ^ {n-. 3) \) . Plus some pruning of memory, you can run through.

70pts

Dfs into the dynamic programming can be transferred. Push down.

Up to 9 digits representing each program by deleting bits.

Defined state \ (dp [i] [sta ] \) represents the now completed the first decision \ (i..n + 1 \) digit, the i-th digit and the state \ (STA \) (binary bit, 0 means delete, 1 expressed reservations).

Then transfer just click above dfs altered enough. The general idea is still above the first pre-sum array, then bit i enumeration, the enumeration state number j, enumerating a digital state k, if \ (sum [i] [j ] <= sum [i + 1] [k] \) is \ (DP [I] [J] + DP = [i + 1] [k] \) .

Time complexity is \ (O (n-\ CDOT. 9 ^ 2 \ 2 ^ CDOT. 9) \) . If the cap is raised when the digital 1e12 when you run any.

100pts

The condition \ (sum [i] [j ] <= sum [i + 1] [k] \) readily occur with prefixes and / or suffixes, and to optimize, without having to enumerate the third layer k.

However, because \ (SUM \) is not incremented, so I have a row order, when the final summation half at first greater than or equal \ (sum [i] [j ] \) position k, such that \ (sum [i ] [J] <= SUM [I +. 1] [K] \) .

Attention to detail.

#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
const int N=103;
ll A,a[N],sum[N][4100],dp[N][4100],tot[N][4100];
int n,num[N][14],len[N];
ll pw[14];

inline void Do(ll &x,ll y){
    x+=y;
    if(x>=mod)x-=mod;
}
int main(){
    scanf("%lld%d",&A,&n);
    register int i,j,k;
    
    pw[0]=1;
    for(i=1;i<=12;++i)pw[i]=pw[i-1]*10;
    
    for(i=0;i<=n;++i)a[i+1]=A+1ll*i;
        
    for(i=1;i<=n+1;++i){
        ll o=a[i];
        while(o){
            num[i][len[i]++]=o%10;
            o/=10;
        }
    }
    for(i=1;i<=n+1;++i){
        for(j=0;j<(1<<len[i]);++j){
            int cnt=0;
            for(k=0;k<len[i];++k)if((1<<k)&j){
                sum[i][j]+=1ll*pw[cnt]*num[i][k];
                ++cnt;
            }
        }       
    }
    
    for(int i=1;i<=n+1;i++)sort(sum[i]+1,sum[i]+(1<<len[i]));
    
    for(i=1;i<(1<<len[n+1]);++i)dp[n+1][i]=1;
    for(j=(1<<len[n+1])-1;j>=1;j--)tot[n+1][j]=(tot[n+1][j]+dp[n+1][j]+tot[n+1][j+1])%mod;
        
    for(i=n;i>=1;i--){//当前轮
        for(j=1;j<(1<<len[i]);++j){
            ll nowj=sum[i][j];
            int o=lower_bound(sum[i+1]+1,sum[i+1]+(1<<len[i+1]),nowj)-sum[i+1];
        //  cout<<"i:"<<i<<" nowj:"<<nowj<<" o:"<<o<<" sumk:"<<sum[i+1][o]<<endl;
        //  cout<<"now add:"<<tot[i+1][o]<<endl;    
            Do(dp[i][j],tot[i+1][o]);
        } 
        for(j=(1<<len[i])-1;j>=1;j--)tot[i][j]=(tot[i][j]+(tot[i][j+1]+dp[i][j])%mod)%mod;
        tot[i][0]=tot[i][1];
    }
        
    ll ans=0;
    for(i=1;i<(1<<len[1]);++i)if(dp[1][i])Do(ans,dp[1][i]);
    printf("%lld\n",(ans+mod)%mod);
}

Guess you like

Origin www.cnblogs.com/Tieechal/p/11584236.html