[数位dp+状态压缩] hdu 4352 XHXJ's LIS

题意:

给x、y、k,在[x,y] 范围内最长上升子序列长度是k的数有几个

思路:

模仿 LIS nlogn的想法,这里就只有10个数,进行状压

然后直接搜就好了不用二分

然后按位dp下去就ok了!

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
//2014年9月26日09:46:04
__int64 dp[22][1024][11];
int num[22];
struct node
{
    int n,l;
};
node js(int n,int x,int tep)
{
    node ans;
    ans.l=tep;
    int i;
    for(i=x; i<10; i++) if(n&(1<<i)) break;
    if(i==10)    //没找到 长度加一 填上那个数
    {
        ans.l=tep+1;
        n|=(1<<x);
    }
    else        //找到  更新那个数
    {
        n^=(1<<i);
        n|=(1<<x);
    }
    ans.n=n;
    return ans;
}
__int64 dfs(int site,int n,int l,int k,int zero,int f)
{
    if(site==0)
    {
        if(zero) return 0;
        return l==k;
    }
    if(!f&&!zero&&~dp[site][n][k]) return dp[site][n][k];
    int len=f?num[site]:9;
    __int64 ans=0;
    for(int i=0; i<=len; i++)
    {
        node tep;
        if(zero)
        {
            if(i==0) ans+=dfs(site-1,n,l,k,zero&&i==0,f&&i==len);
            else
            {
                tep=js(n,i,l);
                ans+=dfs(site-1,tep.n,tep.l,k,zero&&i==0,f&&i==len);
            }
        }
        else
        {
            tep=js(n,i,l);
            ans+=dfs(site-1,tep.n,tep.l,k,zero&&i==0,f&&i==len);
        }
    }
    if(!f&&!zero) dp[site][n][k]=ans;
    return ans;
}
__int64 solve(__int64 x,int k)
{
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%10;
        x/=10;
    }
    return dfs(cnt,0,0,k,1,1);
}
int main()
{
    int t,cas=1;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        __int64 x,y;
        int k;
        scanf("%I64d%I64d%d",&x,&y,&k);
        printf("Case #%d: %I64d\n",cas++,solve(y,k)-solve(x-1,k));
    }
    return 0;
}
//2014年9月26日10:24:07

[数位dp+状态压缩] hdu 4352 XHXJ's LIS

时间: 2024-10-10 16:08:33

[数位dp+状态压缩] hdu 4352 XHXJ's LIS的相关文章

【HDU 4352】 XHXJ&#39;s LIS (数位DP+状态压缩+LIS)

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2422    Accepted Submission(s): 990 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

hdu 4352 数位dp + 状态压缩

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2265    Accepted Submission(s): 927 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

HDU 4352 XHXJ&#39;s LIS (数位DP,状压)

题意: 前面3/4的英文都是废话.将一个正整数看成字符串,给定一个k,问区间[L,R]中严格的LIS=k的数有多少个? 思路: 实在没有想到字符0~9最多才10种,况且也符合O(nlogn)求LIS的特点,所以用状态压缩可以解决. 看到状态压缩的字眼基本就会做了,增加一维来保存当前LIS的状态.由于求LIS时的辅助数组d[i]表示长度为i的LIS最后一个元素,d数组是严格递增的,所以好好利用d数组的特性来设计状态压缩才是关键.压缩的状态0101可以表示:仅有0和2在数组d中,即d[1]=0,d[

hdu 4352 XHXJ&#39;s LIS (数位dp)

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 755    Accepted Submission(s): 289 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful

HDU 4352 XHXJ&#39;s LIS 数位dp

题目链接:点击打开链接 题意: 一个数自身的最长子序列=每一位都是一个数字然后求的LIS 问区间内有多少个数 自身的最长子序列==k 思路: 因为自身的最长子序列至多=10,且由0~9组成,所以状压10个二进制表示0~9中哪些数字已经用过 dp[i][j] 表示长度为i的数字,最长子序列中出现的数字状态j的方法数.由于询问数=K,也存下来避免重复计算. #include <cstdio> #include <algorithm> #include <cstring> #

HDU.4352.XHXJ&#39;s LIS(数位DP 状压 LIS)

题目链接 数位DP. 至于怎么求LIS,因为只有10个数,所以可以参照O(nlogn)求LIS的方法,状压记录状态. 每次加一个数和求LIS一样更新状态.最后状态中1的个数就是LIS的长度. //93MS 3004K #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #define gc() getchar() typedef long long LL; c

HDU - 4352 - XHXJ&#39;s LIS(数位DP)

链接: https://vjudge.net/problem/HDU-4352 题意: a 到 b中一个数组成递增子序列长度等于k的数的个数 思路: 因为只有10个数,使用二进制维护一个递增序列,每次更新在注释写了. 然后正常的数位DP, Dp(i, j, k),i是位置,j是当前的递增状态,k是长度. 考虑一下前缀0,重置状态 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const int MO

HDU 4352 XHXJ&#39;s LIS 数位DP + 状压

由LIS的nlogn解法 可以得出最后统计数组中数的个数即为LIS的长度 这样就可以状压了 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <c

HDU 4352 XHXJ&#39;s LIS

XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1423    Accepted Submission(s): 544 Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then careful