HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
#define xhxj (Xin Hang senior sister(学姐))
If you do not know xhxj, then carefully reading the entire description is very important.
As the strongest fighting force in UESTC, xhxj grew up in Jintang, a border town of Chengdu.
Like many god cattles, xhxj has a legendary life:
2010.04, had not yet begun to learn the algorithm, xhxj won the second prize in the university contest. And in this fall, xhxj got one gold medal and one silver medal of regional contest. In the next year\'s summer, xhxj was invited to Beijing to attend the astar onsite. A few months later, xhxj got two gold medals and was also qualified for world\'s final. However, xhxj was defeated by zhymaoiing in the competition that determined who would go to the world\'s final(there is only one team for every university to send to the world\'s final) .Now, xhxj is much more stronger than ever,and she will go to the dreaming country to compete in TCO final.
As you see, xhxj always keeps a short hair(reasons unknown), so she looks like a boy( I will not tell you she is actually a lovely girl), wearing yellow T-shirt. When she is not talking, her round face feels very lovely, attracting others to touch her face gently。Unlike God Luo\'s, another UESTC god cattle who has cool and noble charm, xhxj is quite approachable, lively, clever. On the other hand,xhxj is very sensitive to the beautiful properties, "this problem has a very good properties",she always said that after ACing a very hard problem. She often helps in finding solutions, even though she is not good at the problems of that type.
Xhxj loves many games such as,Dota, ocg, mahjong, Starcraft 2, Diablo 3.etc,if you can beat her in any game above, you will get her admire and become a god cattle. She is very concerned with her younger schoolfellows, if she saw someone on a DOTA platform, she would say: "Why do not you go to improve your programming skill". When she receives sincere compliments from others, she would say modestly: "Please don’t flatter at me.(Please don\'t black)."As she will graduate after no more than one year, xhxj also wants to fall in love. However, the man in her dreams has not yet appeared, so she now prefers girls.
Another hobby of xhxj is yy(speculation) some magical problems to discover the special properties. For example, when she see a number, she would think whether the digits of a number are strictly increasing. If you consider the number as a string and can get a longest strictly increasing subsequence the length of which is equal to k, the power of this number is k.. It is very simple to determine a single number’s power, but is it also easy to solve this problem with the numbers within an interval? xhxj has a little tired,she want a god cattle to help her solve this problem,the problem is: Determine how many numbers have the power value k in [L,R] in O(1)time.
For the first one to solve this problem,xhxj will upgrade 20 favorability rate。
 
Input
First a integer T(T<=10000),then T lines follow, every line has three positive integer L,R,K.(0<L<=R<263-1 and 1<=K<=10).
 
Output
For each query, print "Case #t: ans" in a line, in which t is the number of the test case starting from 1 and ans is the answer.
 
Sample Input
1
123 321 2
 
Sample Output
Case #1: 139
 
题解:
要说题解哪家强,说到底还是要看kuangbin神犇https://www.cnblogs.com/kuangbin/archive/2013/05/01/3052657.html
dp[i][j][k]:i为当前进行到的数位;
     j为状态,为10个数字出现过的,其中1的个数就是最长上升子序列长度;
     k为要求的上升子序列的长度;
1、这个i好说,就是pos……
2、那这个j这个状态呢,怎么肥4?且先看这篇文章http://www.cnblogs.com/dilthey/p/8511275.html
  在那篇文章里,用了一个d[]数组来存储“当前ans长度下,LIS的最后一位是哪个数字”,
  我们化用一下这个数组d,用0~9十个位的0 or 1来表示,这个d数组里存了啥,比如说假设d[1]=1,d[2]=3,d[3]=5,d[4]=6,那么在本题下的形式就是sta = 0001101010
  然后我们在那篇文章里的,用num[i]更新d[]的行为,就是这里getNewSta()函数干的事情。
3、最后是这个k,我开始不太懂为什么要加这个k,因为我看到每个case中,k都是不变的,一旦设定好了,整个求解过程中dp数组跟k没有关系;
  然后我看了一下,kuangbin大佬的代码,把memset(dp)写在了循环外,我就想到这是用增加一个dp数组的维度,减少memset以及一些重复计算的时间,
  让我刚开始心存侥幸,想不加这个K维度试试,然后交了一发果然TLE,然后只好老老实实再把维度K加上,同时暗叹一声神犇不愧就是神犇啊!
 
AC代码:
 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int K;
int dig[20];
ll dp[20][1<<10][11];

ll getNewSta(ll sta,int num) //运用LIS问题的nlogn思想进行更新状态
{
    for(int i=num;i<=9;i++)
        if(sta&(1<<i)) return (sta^(1<<i))|(1<<num);
    return sta|(1<<num);
}
int get1cnt(ll sta) //获取状态sta中有多少个“1”
{
    int cnt=0;
    while(sta)
    {
        cnt+=sta&1;
        sta>>=1;
    }
    return cnt;
}
ll dfs(int pos,ll sta,bool lead,bool limit) //lead是前导零标记
{
    if(pos==0) return get1cnt(sta)==K; //精确到某一个数,判断其LIS的长度是否等于K
    if(!limit && dp[pos][sta][K]!=-1) return dp[pos][sta][K];

    int up=limit?dig[pos]:9;
    ll ans=0;
    for(int i=0;i<=up;i++)
        ans+=dfs(pos-1,(lead && i==0)?0:getNewSta(sta,i),lead && i==0,limit && i==up);

    if(!limit) dp[pos][sta][K]=ans;
    return ans;
}
ll solve(ll x)
{
    int len=0;
    while(x)
    {
        dig[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,1,1);
}

int main()
{
    int T;
    scanf("%d",&T);
    memset(dp,-1,sizeof(dp));
    for(int kase=1;kase<=T;kase++)
    {
        ll L,R;
        scanf("%I64d%I64d%d",&L,&R,&K);
        printf("Case #%d: %I64d\\n",kase,solve(R)-solve(L-1));
    }
}

以上是关于HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]

HDU 4352 XHXJ's LIS (数位DP+状态压缩+LIS)

hdu4352 XHXJ's LIS(数位dp)

HDU 4352 XHXJ's LIS

HDU 4352 XHXJ's LIS

HDU 4352:XHXJ's LIS