XHXJ's LIS [HDU 4352]
http://acm.hdu.edu.cn/showproblem.php?pid=4352
类似于O(nlog n)的LIS求法,用1<<10记录10以内数的出现情况,贪心更新。
View Code
//类似于O(nlog n)的LIS求法,用1<<10记录10以内数的出现情况,贪心更新。 const int MM = 11111; typedef __int64 int64; int K,cnt, num[MM]; int64 dp[20][1<<10][10],L,R; void get_data() { scanf("%I64d%I64d%d",&L,&R,&K); } int getbit(int state) { int res=0; while(state) state-=lowbit(state),res++; return res; } int getchange(int x,int state) { for(int i=x;i<10;i++) { if(state&(1<<i)) return (state^(1<<i))|(1<<x); } return state|(1<<x); } int64 dfs(int le,int state,bool less,bool ok) { //ok前导0 if(le==-1) return getbit(state)==K; if(!less && dp[le][state][K]!=-1) return dp[le][state][K]; int64 res=0; int d, e=less?num[le]:9; for(d=0;d<=e;d++) { res+=dfs(le-1,state||d!=0?getchange(d,state):0,less&&d==e,ok||d!=0); } if(!less) dp[le][state][K]=res; return res; } int64 cal(int64 x) { for(cnt=0; x ;num[cnt++]=x%10,x/=10); return dfs(cnt-1,0,true,true); } void solve() { printcase(); printf("%I64d\n",cal(R)-cal(L-1)); } int main() { memset(dp,-1,sizeof(dp)); int ca; scanf("%d",&ca); while(ca--) get_data(),solve(); return 0; }