【HDU 4352】 XHXJ'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): 990Problem 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。InputFirst 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).OutputFor 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 Input1
123 321 2Sample OutputCase #1: 139
首先要看出来是数位DP。特点是什么呢,就是跟数的每一位的数字有关。
然后要会LIS的nlogn解法,记录f[i]为当前序列长度为i的上升序列的最后一位最小是什么(因为我们知道最后一位尽量小可能结果更优),当我们新加入一个数x,我们是尝试把它放在f[i]表示的序列后面,看看是不是比f[i+1]优,那么就是找一个f[i]<x<f[i+1]的位置,又因为f数组有单调性(单调不减),所以这样的位置最多只有一个,所以普通的LIS就是二分求出这个位置。
这一题的LIS最长是10,所以我们可以位压直接记录f数组,f数组的size就是当前状态的LIS,并且记录了f就可以保证后面的转移不会错。
然后就数位DP。这次打的数位DP跟以前有点不一样,这题填了数之后对后面的填数还是有影响的,所以不能初始化了。但是可以记忆化搜索,当你的ans与原来的限制数无关(就代码中的flag=0),就可以记录下当前k情况下的ans,那么就省掉了很多了。(猴塞雷啊)
前导0要记得考虑它对状态的影响!
DP[X][S][K]表示当前要算长度为K的LIS,还能填X个数,状态为S(f数组的状压)的方案数,注意flag!=0时才放进去。
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define LL long long int siz[<<],nex[<<][]; int ffind(int x,int y)
{
for(int i=y;i<;i++) if((<<i)&x)
return x-(<<i)+(<<y);
return x+(<<y);
} void init()
{
for(int i=;i<(<<);i++)
{
int x=i;siz[i]=;
while(x) siz[i]+=(x&)?:,x>>=;
for(int j=;j<;j++)
{
nex[i][j]=ffind(i,j);
}
}
} int a[],c,k;
LL f[][<<][]; LL get_f(int n,int s,bool zero,bool flag)
{
if(n==) return (siz[s]==k);
if(!flag&&f[n][s][k]!=-) return f[n][s][k];
int ed=flag?a[n]:;
LL ans=;
for(int i=;i<=ed;i++)
ans+=get_f(n-,(zero&&(i==))?:nex[s][i],zero&&(i==),flag&&(i==ed));
if(!flag) f[n][s][k]=ans;
return ans;
} LL get_ans(LL n)
{
c=;
while(n) a[++c]=n%,n/=;
return get_f(c,,,);
} int main()
{
int T,kase=;
scanf("%d",&T);
init();
memset(f,-,sizeof(f));
while(T--)
{
LL l,r;
scanf("%lld%lld%d",&l,&r,&k);
LL ans=get_ans(r)-get_ans(l-);
printf("Case #%d: %lld\n",++kase,ans);
}
return ;
}
[HDU 4352]
做了这题才发现我没有真的会LIS啊,虽然之前用数据结构也可以做到nlogn,但是套这题就不行了,所以放一下另一个LIS的nlogn解法~~
最长上升子序列nlogn算法
在川大oj上遇到一道题无法用n^2过于是,各种纠结,最后习得nlogn的算法
最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。
排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5。n
下面一步一步试着找出它。
我们定义一个序列B,然后令 i = 1 to 9 逐个考察这个序列。
此外,我们用一个变量Len来记录现在最长算到多少了首先,把d[1]有序地放到B里,令B[1] = 2,就是说当只有1一个数字2的时候,长度为1的LIS的最小末尾是2。这时Len=1
然后,把d[2]有序地放到B里,令B[1] = 1,就是说长度为1的LIS的最小末尾是1,d[1]=2已经没用了,很容易理解吧。这时Len=1
接着,d[3] = 5,d[3]>B[1],所以令B[1+1]=B[2]=d[3]=5,就是说长度为2的LIS的最小末尾是5,很容易理解吧。这时候B[1..2] = 1, 5,Len=2
再来,d[4] = 3,它正好加在1,5之间,放在1的位置显然不合适,因为1小于3,长度为1的LIS最小末尾应该是1,这样很容易推知,长度为2的LIS最小末尾是3,于是可以把5淘汰掉,这时候B[1..2] = 1, 3,Len = 2
继续,d[5] = 6,它在3后面,因为B[2] = 3, 而6在3后面,于是很容易可以推知B[3] = 6, 这时B[1..3] = 1, 3, 6,还是很容易理解吧? Len = 3 了噢。
第6个, d[6] = 4,你看它在3和6之间,于是我们就可以把6替换掉,得到B[3] = 4。B[1..3] = 1, 3, 4, Len继续等于3
第7个, d[7] = 8,它很大,比4大,嗯。于是B[4] = 8。Len变成4了
第8个, d[8] = 9,得到B[5] = 9,嗯。Len继续增大,到5了。
最后一个, d[9] = 7,它在B[3] = 4和B[4] = 8之间,所以我们知道,最新的B[4] =7,B[1..5] = 1, 3, 4, 7, 9,Len = 5。
于是我们知道了LIS的长度为5。
!!!!! 注意。这个1,3,4,7,9不是LIS,它只是存储的对应长度LIS的最小末尾。有了这个末尾,我们就可以一个一个地插入数据。虽然最后一个d[9] = 7更新进去对于这组数据没有什么意义,但是如果后面再出现两个数字 8 和 9,那么就可以把8更新到d[5], 9更新到d[6],得出LIS的长度为6。
然后应该发现一件事情了:在B中插入数据是有序的,而且是进行替换而不需要挪动——也就是说,我们可以使用二分查找,将每一个数字的插入时间优化到O(logN)~~~~~于是算法的时间复杂度就降低到了O(NlogN)~!
至于数位DP,以后再说吧,这样子的记忆化搜索式的数位DP感觉还不错(虽然我以前不是这样打),我现在也没有Y出dfs打法有什么局限性,速度也是很好的。
LL get_f(int n,int s,bool zero,bool flag)
{
if(n==0) return (siz[s]==k);
if(!flag&&f[n][s][k]!=-1) return f[n][s][k];
int ed=flag?a[n]:9;
LL ans=0;
for(int i=0;i<=ed;i++)
ans+=get_f(n-1,(zero&&(i==0))?0:nex[s][i],zero&&(i==0),flag&&(i==ed));
if(!flag) f[n][s][k]=ans;
return ans;
}
2016-10-08 17:08:59
【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)的更多相关文章
- hdu_4352_XHXJ's LIS(数位DP+状态压缩)
题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...
- hdu 4352 XHXJ's LIS 数位dp+状态压缩
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 4352 XHXJ's LIS (数位dp+状态压缩)
Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully readin ...
- HDU.4352.XHXJ's LIS(数位DP 状压 LIS)
题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...
- HDU 2809 God of War(DP + 状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809 题目大意:给出战神吕布的初始攻击力ATI.防御力DEF.生命值HP.每升一级增加的攻击力In_A ...
- hdu4352 数位dp+状态压缩+一个tip
按照nlogn求lis的方法,把lis的状态压缩了,每次新加一个数就把它右边第一个数的位置置为0,然后把这个数加进去 一个需要注意的地方,如果前面都是0,那么状态s中代表0的位置不可以是1,因为这种情 ...
- SPOJ BALNUM - Balanced Numbers - [数位DP][状态压缩]
题目链接:http://www.spoj.com/problems/BALNUM/en/ Time limit: 0.123s Source limit: 50000B Memory limit: 1 ...
- SPOJ BALNUM Balanced Numbers(数位DP+状态压缩)题解
思路: 把0~9的状态用3进制表示,数据量3^10 代码: #include<cstdio> #include<map> #include<set> #includ ...
随机推荐
- JVM中的Stack和Heap
Stack: 是内存指令区.Java基本数据类型,Java指令代码,常量都保存在stack中,方法是指令也保存在stack中. 由于stack是内存是顺序分配,而且定长,不存在内存回收问题.存取速度快 ...
- 移动端布局Demo展示图文
上两张图自勉一下(来自刘墉先生的文章,最近看他的作品):然后移动端该愈来愈受到重视,未来的市场我不知道,不过我知道手机的功能越来越强大是不争的事实!移动端布局的积累也需要从现在做起! 需求一:实现下图 ...
- css怎么写链接到图片和地址
- 在List中找出最大值的两种方法
先说需求:找出一个对象List中,某个属性值最大的对象. 1.定义对象 private class A { public int ID { get; set; } public string Name ...
- ajax 特殊参数值无法传到后台问题
用原生的ajax请求后台的登录功能,使用特殊字符作为密码的时候发现无法把参数传到后台;发现前端就报错了.可能是因为特殊符号吧. 用 encodeURIComponent() 这个方法进行编码之后就可以 ...
- .Net之美读书系列(一):委托与事件
开启新的读书之旅,这次读的书为<.Net之美:.Net关键技术深入解析>. 我是选择性阅读的,把一些自己觉得容易忘记的,或者比较重要的知识点记录下来,以便以后能方便呢查阅. 尊重书本原作者 ...
- web开发学习之旅---css第一天
一.css全称 Cascade Style Sheet层叠样式表 二.css引入方式 行内样式:<h2 style="color:#0F0">Hello World&l ...
- 找不到可安装的ISAM
转载:http://www.cnblogs.com/zyc2/archive/2005/06/28/182492.html 读取excel数据 到 datagrid 出现:找不到可安装的ISAM ...
- ACM——A + B Problem (2)
A + B Problem (2) 时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte总提交:2600 测试通过:137 ...
- C++编程注意事项
1.所有成员变量在构造函数中进行初始化操作,如指针赋值为空,bool赋值为FALSE(默认为TRUE); 2.构造函数与析构函数配对出现,执行反向操作,保证执行析构之后,没有遗留问题存在: 3.如果需 ...