数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
来源:互联网 发布:sql join 编辑:程序博客网 时间:2024/05/20 23:06
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4352
题目意思:
求区间L到R之间的数A满足A的的数位的最长递增序列的长度为K的数的个数。
解题思路:
数位dp+LIS+状态压缩
根据求LIS的nlogn的思想,由于k最多为10,也就是最长递增序列的长度最多为10,可以状态压缩10位,维护前面的已选的递增序列,并及时更新。
dp[i][j][k]表示后面还有i位,前面状态为k,总共需要最长递增序列为j时的总数。
代码:
更新时用两种方式实现都可以。
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#define eps 1e-6#define INF 0x3fffffff#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;ll dp[25][12][1200];int bit[25],cnt,k;ll dfs(int cur,int s,int flag,int num,int * a){ if(!cur) { if(num==k) { dp[cur][num][s]=1; return 1; } return 0; } if(!flag&&dp[cur][k][s]!=-1) return dp[cur][k][s]; ll res=0; int Max=flag?bit[cur]:9; int tmp[25]; for(int i=0;i<=Max;i++) { for(int j=0;j<=num;j++) //如果用二分来写的话,要防止后面最前面数组的改动 tmp[j]=a[j]; if(!s&&!i) //注意前置零,不能记为一个数字 { res+=dfs(cur-1,0,0,0,tmp); continue; } //但当首位不为0时,0又是一个有效的数字 if(i>tmp[num]) //找到一个 { tmp[num+1]=i; res+=dfs(cur-1,s|(1<<i),flag&&(i==Max),num+1,tmp); } else { //找到第一个大于等于的 int t=lower_bound(tmp,tmp+num+1,i)-tmp; int tt=tmp[t]; tmp[t]=i; res+=dfs(cur-1,s-(1<<tt)+(1<<i),flag&&(i==Max),num,tmp); } //第二种实现方式,比较直观,而且复杂度稍微低点/* if((1<<i)>s) res+=dfs(cur-1,s|(1<<i),flag&&(i==Max),num+1); else if((1<<i)&s) res+=dfs(cur-1,s,flag&&(i==Max),num); else { for(int j=i+1;j<=9;j++) { if((1<<j)&s) { res+=dfs(cur-1,(s-(1<<j))|(1<<i),flag&&(i==Max),num); break; } } }*/ } if(!flag) dp[cur][k][s]=res; return res;}ll init(ll a){ cnt=0; while(a) { bit[++cnt]=a%10; a/=10; } int aa[25]; aa[0]=-1; return dfs(cnt,0,1,0,aa);}int main(){ memset(dp,-1,sizeof(dp)); int t; ll a,b; scanf("%d",&t); for(int ca=1;ca<=t;ca++) { scanf("%I64d%I64d%d",&a,&b,&k); //printf("%I64d %I64d\n",init(a,k),init(b,k)); printf("Case #%d: %I64d\n",ca,init(b)-init(a-1)); } return 0;}
- 数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
- hdu 4352 XHXJ's LIS --- 数位dp 状态压缩
- [数位dp+状态压缩] hdu 4352 XHXJ's LIS
- HDU 4352 XHXJ's LIS (数位DP+状态压缩)
- HDU 4352 XHXJ's LIS(数位dp&状态压缩)
- HDU 4352 XHXJ's LIS(状态压缩+数位dp)
- hdu 4352 XHXJ's LIS(数位dp进阶,LIS, 状态压缩)
- HDU 4352 XHXJ's LIS(数位DP+LIS+状态压缩)
- hdu4352 XHXJ's LIS(数位DP + LIS + 状态压缩)
- hdu 4352 XHXJ's LIS (数位+状态DP)
- 【HDU】4352 XHXJ's LIS 数位DP
- 【数位DP】【hdu 4352】XHXJ's LIS
- HDU 4352 XHXJ's LIS 数位dp
- HDU 4352 XHXJ's LIS(数位DP)
- hdu 4352 XHXJ's LIS(数位dp)
- HDU 4352 XHXJ's LIS【数位DP】
- hdu 4352 XHXJ's LIS(LIS+数位DP,5级)
- HDU 4352 XHXJ's LIS 数位dp+lis
- 11. 求二叉树中节点的最大距离
- 二叉树的前序、中序、后序遍历(非递归)
- [转]apache下如何增加网站for linux(绑定域名)
- 如何在ubuntu13.04启动ssh
- 各种编程语言和方式对比
- 数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS
- 系统设计之粒度控制
- Java 基础加强 - 反射Reflect
- 协方差与自相关
- 如何在GWT实现点击Button(或其他Widget)打开文件选择对话框
- HDOJ,杭电1877,又一版A+B。。又是进制转化的题目。。
- HTTP协议详解
- [Friends]S03E01
- 数学专项counting:LA 3720