码迷,mamicode.com
首页 > 其他好文 > 详细

hdu4352_状压+数位+lis

时间:2016-08-18 00:46:34      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

原文:http://www.acmerblog.com/hdu-4352-xhxjs-lis-7363.html

 * 问L到R,各位数字组成的严格上升子序列的长度为K的个数。
 * 0<L<=R<263-1 and 1<=K<=10
 * 注意这里最长上升子序列的定义,和LIS是一样的,不要求是连续的
 * 所以用十位二进制表示0~9出现的情况,和O(nlogn)求LIS一样的方法进行更新
技术分享
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 int bit[35];
17 LL dp[35][15][1 << 10], k;
18 
19 int GetNext(int st,int x)  
20 {  //刚开始用数组存,会超时啊(大哭),还是太嫩了
21     //找到第一个大于x的数并且替换他,nlogn求最长递增子序列的思想  
22     for(int i=x;i<10;i++)  
23         if(st&(1<<i)) return ((st^(1<<i))|(1<<x));  
24     return st|(1<<x);  
25 }  
26 int GetLen(int st)  
27 {  
28     int cnt=0;  
29     while(st)  
30     {  
31         if(st&1) cnt++;  
32         st>>=1;  
33     }  
34     return cnt;  
35 }  
36 LL dfs(int len, int length, int mark, int flag)
37 {//刚开始一直用dp[len][length][mark], 跟length没有毛线关系啊,wa了n发
38     if(len == 0)
39         return GetLen(mark) == k;
40     if(flag && dp[len][k][mark] >= 0)
41         return dp[len][k][mark];
42     LL sum = 0;
43     int te = flag ? 9 : bit[len];
44     for(int i = 0; i <= te; i++)
45     {
46         int Mark = ((length==0 && i==0) ? 0 : GetNext(mark, i));
47         sum += dfs(len - 1, length || i , Mark, flag || (i < te));
48     }
49     if(flag)
50         dp[len][k][mark] = sum;
51     return sum;
52 }
53 LL solve(LL n)
54 {
55     int len = 0;
56     while(n)
57     {
58         bit[++len] = n % 10;
59         n /= 10;
60     }
61     return dfs(len, 0, 0, 0);
62 }
63 int main()
64 {
65     int t;
66     LL l, r;
67     scanf("%d", &t);
68     memset(dp, -1, sizeof(dp));
69     for(int i = 1; i <= t; i++)
70     {
71         cin >> l >> r >> k;
72         cout << "Case #"<< i << ": ";
73         cout << solve(r) - solve(l - 1) << endl;
74     }
75     return 0;
76 }
View Code

 

hdu4352_状压+数位+lis

标签:

原文地址:http://www.cnblogs.com/luomi/p/5782265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!