您的位置:首页 > 其它

hdu 4352 统计数字数位上最长上升子序列长度为k的个数

2013-05-21 19:25 417 查看
题意:

1245 这个数属于上升长度为4的数字,1213这个数字属于上升长度为3的数字。

统计区间[l,r]中上升长度为k的数字个数。

State 状态压缩,表示最长上升的序列用到的数字有哪些

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
typedef long long LL;
int const N = 22;
int const M = 1030;
int bit
,ln,pow2[11],k;
LL dp
[M][20];
void pre()
{
pow2[0]=1;
for(int i=1;i<=10;i++)pow2[i]=(pow2[i-1]<<1);
}
LL getsum1(int t,int limit,int len,int state)
{
if(!t)return (len==k);
if(!limit&&dp[t][state][k]!=-1)return dp[t][state][k];
int up=(limit?bit[t]:9);
LL ans=0;
for(int i=0;i<=up;i++)
{
if(state||i)
{
if(pow2[i]>state)
{
ans+=getsum1(t-1,limit&&i==up,len+1,state|pow2[i]);
}
if(pow2[i]&state)
{
ans+=getsum1(t-1,limit&&i==up,len,state);
}
else
{
for(int j=i+1;j<=9;j++)
{
if(state&pow2[j])
{
ans+=getsum1(t-1,limit&&i==up,len,state^pow2[j]|pow2[i]);
break;
}
}
}
}
else
{
ans+=getsum1(t-1,limit&&i==up,0,0);
}
}
if(!limit)dp[t][state][k]=ans;
return ans;
}
LL getsum2(LL n)
{
if(n==0)return 0;
for(ln=0;n;bit[++ln]=n%10,n/=10);
return getsum1(ln,1,0,0);
}
int main()
{
pre();
memset(dp,-1,sizeof(dp));
int T,t=0;
k=2;
scanf("%d",&T);
while(T--)
{
LL l,r;
scanf("%I64d %I64d",&l,&r);
scanf("%d",&k);
l--;
printf("Case #%d: %I64d\n",++t,getsum2(r)-getsum2(l));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: