首页 > 代码库 > hdu 4352
hdu 4352
搞半天才懂
求区间L到R之间的数A满足A的的数位的最长递增序列的长度为K的数的个数。
s是各数字状态压缩后的
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define maxn 205typedef long long ll;using namespace std;ll n,m,ans,tot,le,ri,k;ll dig[20],dp[20][1<<11][11];ll getstate(ll s,ll u,ll& xx) // 状态转移{ ll i,ss; for(i=u;i<10;i++) { if(s&(1<<i)) break ; } if(i<10) { ss=s^(1<<i); ss=ss^(1<<u); } else { xx++; ss=s^(1<<u); } return ss;}ll dfs(ll pos,ll s,ll len,ll flg,ll lead) // 当前位 LIS状态 LIS长度 上界标志 前导0标志{ if(pos==0) { if(len==k) return 1; return 0; } if(!flg&&dp[pos][s][k]!=-1) return dp[pos][s][k]; ll i,j,t,ed,res=0; if(flg) ed=dig[pos]; else ed=9; for(i=0;i<=ed;i++) { ll ss,nlen=len; if(lead==0&&i==0) ss=0; else ss=getstate(s,i,nlen); t=dfs(pos-1,ss,nlen,flg&&i==ed,lead||i!=0); res+=t; } if(!flg) dp[pos][s][k]=res; return res;}ll solve(ll x){ ll i,j,t=x; tot=0; while(t) { dig[++tot]=t%10; t/=10; } ll res=dfs(tot,0,0,1,0); return res;}int main(){ ll i,j,t,test=0; memset(dp,-1,sizeof(dp)); scanf("%I64d",&t); while(t--) { scanf("%I64d%I64d%I64d",&le,&ri,&k); ans=solve(ri)-solve(le-1); printf("Case #%I64d: %I64d\n",++test,ans); } return 0;}
hdu 4352
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。