HDU 4352 XHXJ's LIS

主宰稳场 提交于 2019-11-28 16:26:46

奇妙的题。

你先得会另外一个nlogn的LIS算法。(我一直只会BIT。。。。。)

然后维护下每个数码作为结尾出现过没有就完了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
long long t,l,r,k,ret=0,bit[21];
struct pnt
{
    long long k[11];
}dp[22][1<<10];
void reset()
{
    for (long long i=0;i<=21;i++)
        for (long long j=0;j<(1<<10);j++)
            for (long long k=0;k<=10;k++)
                dp[i][j].k[k]=-1;
}
void get_bit(long long x)
{
    ret=0;
    while (x) {bit[++ret]=x%10;x/=10;}
}
long long bit_cnt(long long x)
{
    long long ret=0;
    while (x) {if (x&1) ret++;x>>=1;}
    return ret;
}
long long get_sets(long long sets,long long x)
{
    if (sets&(1<<x)) return sets;
    sets|=(1<<x);
    for (long long i=x+1;i<=9;i++)
    {
        if (sets&(1<<i))
        {
            sets^=(1<<i);
            return sets;
        }
    }
    return sets;
}
pnt comb(pnt x,pnt y)
{
    for (long long i=1;i<=10;i++)
        x.k[i]+=y.k[i];
    return x;
}
pnt dfs(long long pos,long long sets,bool flag)
{
    if (!pos)
    {
        long long now=bit_cnt(sets);pnt ret;
        for (long long i=1;i<=10;i++)
        {
            if (i==now) ret.k[i]=1;
            else ret.k[i]=0;
        }
        return ret;
    }
    if ((!flag) && (~dp[pos][sets].k[1])) return dp[pos][sets];
    pnt ans;long long up=flag?bit[pos]:9;
    for (long long i=1;i<=10;i++) ans.k[i]=0;
    for (long long i=0;i<=up;i++)
        ans=comb(ans,dfs(pos-1,get_sets(sets,i),flag&&i==up));
    if (!flag) dp[pos][sets]=ans;
    return ans;
}
long long ask(long long x)
{
    if (!x) return 0;
    get_bit(x);long long ans=0;
    for (long long i=1;i<=ret-1;i++)
        for (long long j=1;j<=9;j++)
            ans+=dfs(i-1,1<<j,0).k[k];
    for (long long j=1;j<=bit[ret]-1;j++)
        ans+=dfs(ret-1,1<<j,0).k[k];
    ans+=dfs(ret-1,1<<bit[ret],1).k[k];
    return ans;
}
void work(long long x)
{
    scanf("%lld%lld%lld",&l,&r,&k);
    printf("Case #%lld: %lld\n",x,ask(r)-ask(l-1));
}
int main()
{
    scanf("%lld",&t);reset();
    for (long long i=1;i<=t;i++) work(i);
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!