【HDU4352】 XHXJ's LIS

来源:互联网 发布:大数据 a股 编辑:程序博客网 时间:2024/06/05 02:14

Problem

http://acm.hdu.edu.cn/showproblem.php?pid=4352

Solution

数位DP+LIS+状压
解题前奏:nlogn LIS
具体:记录前len位的LIS情况,可以预处理sta+i后的newsta,然后DFS,DP写超时(10000组)

CODE

/* * @key word:digit DP * @tesed on:HDU4352 62ms * @Author: lhq  * @Date: 2017-08-15 12:30:13  * @Last Modified by: lhq * @Last Modified time: 2017-08-15 12:30:36 */#include<cstdio>#include<iostream>#include<cstring>using namespace std;#define ll long longint change[1<<10][10],one[1<<10],a[20],K;ll dp[20][1<<10][11];ll dfs(int len,int sta,bool limit){    if (len==0) return one[sta]==K?1:0;    if (!limit && dp[len][sta][K]!=-1) return dp[len][sta][K];    int up=limit?a[len]:9;    ll ans=0;    for (int i=0;i<=up;i++)        ans+=dfs(len-1,change[sta][i],limit && i==up);    if (!limit) dp[len][sta][K]=ans;    return ans;}ll solve(ll x){    int len=0;    while (x)    {        a[++len]=x%10;        x/=10;    }    return dfs(len,0,true);}void prepare(){    memset(dp,-1,sizeof(dp));    for (int i=0;i<1<<10;i++)        for (int j=0;j<=9;j++)        {            if (i==0 && j==0) continue;            int p=i;            for (int k=j;k<=9;k++)                if (p & (1<<k)) {p^=1<<k; break;}            change[i][j]=p^(1<<j);        }    for (int i=0;i<1<<10;i++)        for (int j=0;j<=9;j++)            if (i & 1<<j) one[i]++;}int main(){    prepare();    int T;    cin>>T;    for (int i=1;i<=T;i++)    {        ll l,r;        scanf("%lld%lld%d",&l,&r,&K);        printf("Case #%d: %lld\n",i,solve(r)-solve(l-1));    }    return 0;}