Digital DP-God template Detailed
To make it easy for me to see, I'll copy the code.
//pos = current processing position (usually from high to low)//pre = number of the previous bit (higher bit)//status = The state to be reached, 1 can be thought to have found the answer, then used to return,//to the counter +1. //Limit = Whether it is restricted, that is, the current processing of this can be random value. such as 567, currently dealing with 6 this,//If the previous fetch is 4, the current one can fetch 0-9. If the previous fetch is 5, then the current//This can not be taken casually, otherwise it will exceed the range of this number, so if the front of the 5//the limit=1 at this time, that is to say, only 0-6 can be taken at present. ////the three states are saved with a DP array because there is a lot of repetition when you move back. intDfsintPosintPreintStatusintlimit) { //The end of the search, return to the "whether the answer found" this state. if(Pos <1) returnstatus; //The DP holds the complete, or unrestricted, answer, so you can return it directly if it is satisfied. if(!limit && dp[pos][pre][status]! =-1) returnDp[pos][pre][status]; intEnd = limit? Dig[pos]:9; intRET =0; //The status of the search is very ingenious, status by | | Because if we find the answer in front, then the back.//Whether or not the answer is irrelevant. And Limti && is because only the front limited, the current limited ability//The next step is also limited, such as 567, if the case is 46X, although 6 has reached the end, but the back of the//the digit can still be taken casually, because the hundred is not limited, so if the bit to be limited, then the front must be 56. // //Here is an example of "Don't 49". for(inti =0; I <= End;i + +) ret+ = DFS (pos-1, I,status | | (Pre = =4&& i = =9), limit && (i = =end)); //Save the complete, end-of-date data in the DP if(!limit) Dp[pos][pre][status]=ret; returnret;}
Portal Hdu 5787 k-wolf number
Spit Groove: I used to write a number of DP, but also stay on the surface of the understanding, so although I see the topic on the algorithm, but, eh, did not get out ... Feel yourself good slag!!!
Test instructions: Give you an interval that allows you to find the number of numbers that do not have the same number in any k digits
Idea: This idea is more consistent, Dp[pos][a][b][c][d] POS represents the current bit, a,b,c,d represents the former 4,3,2,1 bit respectively. Here is the case of the leading 0, which means that the previous bit is 0 when d=10. So when (d==10 && i==0) The current one is 0 and the first four bits are 0. So down Dfs words ans+=dfs (temp-1,a,b,c,d,limit && (i==ed));
/************************************************************** problem:hdu 5787 K-wolf number User:youmi Lang uage:c++ result:accepted time:265ms memory:3872k*************************************************************** *///#pragma COMMENT (linker, "/stack:1024000000,1024000000")//#include <bits/stdc++.h>#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<stack>#include<Set>#include<sstream>#include<cmath>#include<queue>#include<deque>#include<string>#include<vector>#defineZeros (a) memset (A,0,sizeof (a))#defineOnes (a) memset (A,-1,sizeof (a))#defineSC (a) scanf ("%d", &a)#defineSC2 (A, b) scanf ("%d%d", &a,&b)#defineSC3 (a,b,c) scanf ("%d%d%d", &a,&b,&c)#defineSCS (a) scanf ("%s", a)#defineSclld (a) scanf ("%i64d", &a)#definePT (a) printf ("%d\n", a)#definePtlld (a) printf ("%i64d\n", a)#defineRep (i,from,to) for (int i=from;i<=to;i++)#defineIrep (I,to,from) for (int i=to;i>=from;i--)#defineMax (a) (a) > (b)? ( A):(B))#defineMin (a) < (b) ( A):(B))#defineLson (step<<1)#defineRson (lson+1)#defineEPS 1e-6#defineOO 0x3fffffff#defineTEST cout<< "*************************" <<endlConst DoublePi=4*atan (1.0);using namespaceStd;typedefLong Longll;template<classT> InlinevoidRead (T &N) { CharCintFlag =1; for(c = GetChar ();! (c >='0'&& C <='9'|| c = ='-'); c = GetChar ());if(c = ='-') flag =-1, n =0;Elsen = C-'0'; for(c = GetChar (); C >='0'&& C <='9'; c = GetChar ()) n = n *Ten+ C-'0'; N *=Flag;}intPow (int Base, ll N,intmo) { if(n = =0)return 1; if(n = =1)return Base%mo; intTMP = Pow (Base, N >>1, MO); TMP= (LL) TMP * TMP%mo; if(N &1) TMP = (LL) TMP *Base%mo; returntmp;}//***************************ll K;ll dp[ -][ One][ One][ One][ One];intdt[ -];inttt;BOOLCheckintTempintAintBintCintd) { if(k==2) { if(temp==d)return true; } Else if(k==3) { if(temp==d| | temp==c)return true; } Else if(k==4) { if(temp==d| | temp==c| | temp==b)return true; } Else if(k==5) { if(temp==d| | temp==c| | temp==b| | temp==a)return true; } return false;} ll Dfs (intTempintAintBintCintDintlimit) { if(temp<0) return1ll; ll& now=Dp[temp][a][b][c][d]; if(!limit&&Now )returnNow ; ll ans=0; intED=LIMIT?DT[TEMP]:9; for(intI=0; i<=ed;i++) { if(check (i,a,b,c,d))Continue; if(i==0&&d==Ten) ans+=dfs (temp-1,a,b,c,d,limit&& (i==ed)); Elseans+=dfs (temp-1,b,c,d,i,limit&& (i==ed)); } if(!limit) now=ans; returnans;} ll Sovle (ll N) {TT=0; while(n) {Dt[tt++]=n%Ten; N/=Ten; } zeros (DP); returnDFS (tt-1,Ten,Ten,Ten,Ten,1);}intMain () {#ifndef Online_judge freopen ("In.txt","R", stdin); Freopen ("OUT.txt","W", stdout); #endifll L,r; while(~SCANF ("%i64d%i64d%i64d",&l,&r,&k)) {printf ("%i64d\n", Sovle (R)-sovle (l1)); }}
View Code
HDU 5787 K-wolf number digits DP