hdu4352 XHXJ's LIS(数位DP + LIS + 状态压缩)
2016-05-31 11:44
405 查看
题目点我点我点我
题目大意:求L到R中有多少个数符合各位数字组成长度为K的LIS。
解题思路:用LIS的nlogn的方法解,如:
现在LIS是2,5,8,9。最新的是3,然后就把状态更新为2,3,8,9。
又因为只有0-9这10个数字,用二进制状态压缩记录状态。
dp[i][j][k]表示i位数,状态为j时的LIS为k的数量。
除了注意数字的上界外,还必须注意数字位数长度与状态的更新,每换新长度时都必须初始化状态,如:
现在有一个5位数,枚举了5位数后,然后就开始枚举4位数,此时就必须将状态s重置为0,即把最高位看作0。
所以我这里用z记录前面是否都为0,若为真,即这是一个新的长度的数,重置状态s。
题目大意:求L到R中有多少个数符合各位数字组成长度为K的LIS。
解题思路:用LIS的nlogn的方法解,如:
现在LIS是2,5,8,9。最新的是3,然后就把状态更新为2,3,8,9。
又因为只有0-9这10个数字,用二进制状态压缩记录状态。
dp[i][j][k]表示i位数,状态为j时的LIS为k的数量。
除了注意数字的上界外,还必须注意数字位数长度与状态的更新,每换新长度时都必须初始化状态,如:
现在有一个5位数,枚举了5位数后,然后就开始枚举4位数,此时就必须将状态s重置为0,即把最高位看作0。
所以我这里用z记录前面是否都为0,若为真,即这是一个新的长度的数,重置状态s。
/* *********************************************** ┆ ┏┓ ┏┓ ┆ ┆┏┛┻━━━┛┻┓ ┆ ┆┃ ┃ ┆ ┆┃ ━ ┃ ┆ ┆┃ ┳┛ ┗┳ ┃ ┆ ┆┃ ┃ ┆ ┆┃ ┻ ┃ ┆ ┆┗━┓ 马 ┏━┛ ┆ ┆ ┃ 勒 ┃ ┆ ┆ ┃ 戈 ┗━━━┓ ┆ ┆ ┃ 壁 ┣┓┆ ┆ ┃ 的草泥马 ┏┛┆ ┆ ┗┓┓┏━┳┓┏┛ ┆ ┆ ┃┫┫ ┃┫┫ ┆ ┆ ┗┻┛ ┗┻┛ ┆ ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> using namespace std; #define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++) #define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--) const int inf_int = 2e9; const long long inf_ll = 2e18; #define inf_add 0x3f3f3f3f #define mod 1000000007 #define LL long long #define ULL unsigned long long #define MS0(X) memset((X), 0, sizeof((X))) #define Sd(X) int (X); scanf("%d", &X) #define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y) #define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z) LL dp[20][1<<10][11]; int k; int bit[20]; int update(int x,int s) { for(int i=x;i<10;i++) { if(s&(1<<i)) return (s^(1<<i))|(1<<x); } return s|(1<<x); } int getK(int s) { int cnt = 0; while(s) { if(s&1)cnt++; s >>= 1; } return cnt; } LL dfs(int pos,int s,bool e,bool z) //e为上界,z记录前面的是否都为0 { if(!pos)return getK(s) == k; if(!e && dp[pos][s][k]!=-1) return dp[pos][s][k]; int digit = e ? bit[pos] : 9; LL ans = 0; for(int i=0;i<=digit;i++) { ans += dfs(pos-1,(z && (i==0)) ? 0 : update(i,s),e && i==digit,z && (i==0)); } if(!e)dp[pos][s][k] = ans; return ans; } LL solve(LL n) { int len = 0; while(n) { bit[++len] = n%10; n /= 10; } return dfs(len,0,1,1); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); Sd(t); int cas = 1; memset(dp,-1,sizeof dp); while(t--) { LL a,b; cin>>a>>b>>k; printf("Case #%d: %I64d\n",cas++,solve(b)-solve(a-1)); } return 0; }
相关文章推荐
- 每个决策都需要一个反对委员会
- 解决nginx负载均衡的session共享问题
- Eclipse使用maven构建web项目
- Cisco MDS 9124 官网配置
- Scala 强大的集合数据操作示例
- xUtils更新到3.0后的基本使用规则
- JavaScript UI Library, Ajax Components & HTML5 Framework - DHTMLX
- 二路归并排序算法实现-完整C语言程序
- 手机网站keyup解决方案
- BZOJ 1083: [SCOI2005]繁忙的都市 裸的最小生成树
- 用BufferedReader或者writer时要注意close
- 常量和变量的区别
- Android调用第三方QQ登录代码分享
- WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptRes
- su: Authentication failure
- Intersection of Two Linked Lists
- 操作系统的书籍
- Oracle误删Undo后恢复
- 公司搬家
- 51NOD 1434 区间LCM(素数筛)