HDU 4352

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <string.h>
 5 #include <algorithm>
 6 #define LL __int64
 7 using namespace std;
 8
 9 LL dp[25][1<<10][11];
10 LL aa,bb;
11 int a[30],k;
12 /*这道题的难点就在于DP的状态表示了,确实是这样的。DP【pos】【state】【K】,pos表示当前的数位,state表示当前的LIS的状态,K
13 表示要求的K长度。那个DFS就不解释了,都成模板了。而对于state的转移,是用二进制表示当前状态,因为最长的
14 序列就是0~9十个数表示,所以有十位的二进制。例如12456的上升序列,下一次出现3,则可表示为12356,至于转移,要联系nlogn解法的
15 LIS来看了 */
16 int getnews(int x,int s){
17     for(int i=x;i<10;i++)
18         if(s&(1<<i))return (s^(1<<i))|(1<<x);
19     return s|(1<<x);
20 }
21 int getnum(int s){
22     int ret=0;
23     while(s)
24     {
25         if(s&1)ret++;
26         s>>=1;
27     }
28     return ret;
29 }
30
31 LL dfs(int len,int st,bool zero,bool flag){
32     if(len==0) return getnum(st)==k;
33     if(!flag&&dp[len][st][k]!=-1)
34     return dp[len][st][k];
35     int en=flag?a[len]:9;
36     LL ans=0;
37     for(int i=0;i<=en;i++){
38         ans+=dfs(len-1,(zero&&i==0)?0:getnews(i,st),zero&&i==0,flag&&i==en);
39     }
40     if(!flag) dp[len][st][k]=ans;
41     return ans;
42 }
43
44 LL cal(LL n){
45     LL tmp=n;
46     int len=0;
47     while(tmp){
48         a[++len]=(int)(tmp%10);
49         tmp/=10;
50     }
51     return dfs(len,0,true,true);
52 }
53
54 int main(){
55     memset(dp,-1,sizeof(dp));
56     int T,t=0;
57     scanf("%d",&T);
58     while(++t<=T){
59         scanf("%I64d%I64d%d",&aa,&bb,&k);
60         printf("Case #%d: %I64d\n",t,cal(bb)-cal(aa-1LL));
61     }
62     return 0;
63 }

时间: 2024-11-10 14:00:00

HDU 4352的相关文章

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

hdu 4352 数位dp(最长上升子序列的长度为k的个数)

http://acm.hdu.edu.cn/showproblem.php?pid=4352 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

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 数位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,状压)

题意: 前面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&amp;#39;s LIS(数位dp&amp;amp;状态压缩)

题目链接:[kuangbin带你飞]专题十五 数位DP B - XHXJ's LIS 题意 给定区间.求出有多少个数满足最长上升子序列(将数看作字符串)的长度为k. 思路 一个数的上升子序列最大长度为10,所以每个上升子序列的状态都能够用10个二进制位来表示. 上升子序列的变化能够用LIS的方式来更新. dp[len][num][k] len为当前的位,num为当前上升子序列的状态.k表示子序列的长度. next[s][num]为记录预处理的子序列的状态变化. cnt [num]记录各个状态的最

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

数位dp专题 (HDU 4352 3652 3709 4507 CodeForces 55D POJ 3252)

数位dp核心在于状态描述,因为阶段很简单. 一般都是求有多少个数,当然也有求平方的变态题. 因为比这个数小的范围定然是从左至右开始小的,那么什么样的前缀对后面子数有相同的结果? HDU 3652 题意:求能被13整除且含有13这样数的个数. 赤裸裸的两个条件,加上个pre标明下前缀,其实直接开状态也是一样的.整除这个条件可以用余数来表示.余数转移:(mod*10+i)%13 /* *********************************************** Author :bi

【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

[数位dp+状态压缩] hdu 4352 XHXJ&#39;s LIS

题意: 给x.y.k,在[x,y] 范围内最长上升子序列长度是k的数有几个 思路: 模仿 LIS nlogn的想法,这里就只有10个数,进行状压 然后直接搜就好了不用二分 然后按位dp下去就ok了! 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"al