【HDU4352】 XHXJ's LIS

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 long
int 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章