First consider the Nlogn solution of LIS
We use Dp[len] to record the size of the last number when the LIS length is Len, and then update these values continuously so that each value is as small as possible
For example, my current LIS is 1 2 4 6, when the next number is 3, then we will be updated to 1 2 3 6, so that the previous number as small as possible, so that the number of the latter will have more opportunities to join
Because the number is only 10, we can state compression, record whether each number is present so that the previous number is as small as possible in the LIS
And then when you move, if you add a num after the status STA, find the first number greater than or equal to NUM, replace it with NUM, and add num if there is no larger number than num
This ensures that the previous number is as small as possible and does not change the length of the LIS
The above mentioned transfer can be preprocessed, Next[i][j] indicates that the original state is I, plus a number J after the state
DP[DEP][STA][K] Record length of Dep,lis is the answer when Sta,lis is K
Note the leading 0
1#include <bits/stdc++.h>2 using namespacestd;3typedefLong Longll;4 intnext[1<<Ten][Ten],dig[ -];5ll dp[ -][1<<Ten][Ten],cnt[1<<Ten];6ll Get_next (intStaintnum) {7 intpos=-1;8 for(inti=num;i<Ten; i++)9 if(sta& (1<<i)) {pos=i; Break; }Ten if(pos==-1) sta|= (1<<num); One ElseSta= (sta^ (1<<pos)) | (1<<num);// A returnSTA; - } - voidPP () { thememset (dp,-1,sizeof(DP)); - for(intI=0;i< (1<<Ten); i++) - for(intj=0;j<Ten; j + +){ - if(i& (1<<J)) cnt[i]++; +next[i][j]=Get_next (i,j); - } + } All Dfs (intDepintStaintKintFlagintZero) { at if(!DEP)returnCnt[sta]==k?1LL:0LL; - if(!flag&&dp[dep][sta][k]!=-1)returnDp[dep][sta][k]; - intLIM=FLAG?DIG[DEP]:9; -ll ans=0; - for(intI=0; i<=lim;i++){ - if(zero&&i==0) Ans+=dfs (dep-1,0,k,flag& (I==lim),1); in ElseAns+=dfs (dep-1,next[sta][i],k,flag& (I==lim),0); - } to if(!flag) dp[dep][sta][k]=ans; + returnans; - } the ll solve (ll x,ll K) { * intDd=0; $ while(x) dig[++dd]=x%Ten, x/=Ten;Panax Notoginseng returnDFS (DD,0K1,1);// - } the intMain () { + PP (); A intT; thescanf"%d",&T); +ll A, B;intK; - for(intCase=1; case<=t; case++){ $scanf"%lld%lld%d",&a,&b,&K); $printf"Case #%d:%lld\n", Case,solve (b,k)-solve (a1, K)); - } - return 0; the}
View Code
[HDU4352] Xhxj ' s LIS