【HDU】4352 XHXJ's LIS(数位dp+状压)
题目
传送门:QWQ
分析
数位dp
状压一下现在的$ O(nlogn) $的$ LIS $的二分数组
数据小,所以更新时直接暴力不用二分了。
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=20; ll dp[maxn][1<<11][12];int k,digit[maxn]; int nextstate(int state,int x){ for(int i=x;i<10;i++){ if(state&(1<<i)){ state^=(1<<i); break; } } return (state|(1<<x)); } int getnum(int x){ int ans=0; while(x){ if(x&1) ans++; x>>=1; } return ans; } ll dfs(int pos,int state,int leadingzero,int border){ if(pos==0) return getnum(state)==k; if(!leadingzero && !border && dp[pos][state][k]!=-1) return dp[pos][state][k]; ll ans=0; int end=border?digit[pos]:9; for(int i=0;i<=end;i++){ if(i==0 && leadingzero) ans+=dfs(pos-1,state,1,border&&i==end); else ans+=dfs(pos-1,nextstate(state,i),0,border&&i==end); } if(!leadingzero&&!border) dp[pos][state][k]=ans; return ans; } ll cal(ll n){ int pos=0; while(n){ digit[++pos]=n%10; n/=10; } return dfs(pos,0,1,1); } int main(){ int t;ll l,r; cin>>t; memset(dp,-1,sizeof(dp)); for(int i=1;i<=t;i++){ cin>>l>>r>>k; cout<<"Case #"<<i<<": "<<cal(r)-cal(l-1)<<endl; } return 0; } /* 100 1234567 123456789012 8 5678567890101 1234567890123456 9 */