题意:
1245 这个数属于上升长度为4的数字,1213这个数字属于上升长度为3的数字。
统计区间[l,r]中上升长度为k的数字个数。
State 状态压缩,表示最长上升的序列用到的数字有哪些
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 typedef long long LL; 6 int const N = 22; 7 int const M = 1030; 8 int bit[N],ln,pow2[11],k; 9 LL dp[N][M][20]; 10 void pre() 11 { 12 pow2[0]=1; 13 for(int i=1;i<=10;i++)pow2[i]=(pow2[i-1]<<1); 14 } 15 LL getsum1(int t,int limit,int len,int state) 16 { 17 if(!t)return (len==k); 18 if(!limit&&dp[t][state][k]!=-1)return dp[t][state][k]; 19 int up=(limit?bit[t]:9); 20 LL ans=0; 21 for(int i=0;i<=up;i++) 22 { 23 if(state||i) 24 { 25 if(pow2[i]>state) 26 { 27 ans+=getsum1(t-1,limit&&i==up,len+1,state|pow2[i]); 28 } 29 if(pow2[i]&state) 30 { 31 ans+=getsum1(t-1,limit&&i==up,len,state); 32 } 33 else 34 { 35 for(int j=i+1;j<=9;j++) 36 { 37 if(state&pow2[j]) 38 { 39 ans+=getsum1(t-1,limit&&i==up,len,state^pow2[j]|pow2[i]); 40 break; 41 } 42 } 43 } 44 } 45 else 46 { 47 ans+=getsum1(t-1,limit&&i==up,0,0); 48 } 49 } 50 if(!limit)dp[t][state][k]=ans; 51 return ans; 52 } 53 LL getsum2(LL n) 54 { 55 if(n==0)return 0; 56 for(ln=0;n;bit[++ln]=n%10,n/=10); 57 return getsum1(ln,1,0,0); 58 } 59 int main() 60 { 61 pre(); 62 memset(dp,-1,sizeof(dp)); 63 int T,t=0; 64 k=2; 65 scanf("%d",&T); 66 while(T--) 67 { 68 LL l,r; 69 scanf("%I64d %I64d",&l,&r); 70 scanf("%d",&k); 71 l--; 72 printf("Case #%d: %I64d\n",++t,getsum2(r)-getsum2(l)); 73 } 74 return 0; 75 }