HDU 4352 XHXJ's LIS (数位DP+状态压缩)
2015-07-22 15:38
351 查看
最长递增子序列很自然就想到二分(nlogn)的算法,用状态S存储二分后的答案,第i位为1就是i存在于二分的答案中。
注意前导0。
我的代码:
注意前导0。
我的代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; typedef __int64 LL; const int inf = 0x3f3f3f3f; LL dp[20][1<<10][11],l,r,k; LL bit[20],top; int tm[20]; int get_news(int s,int d){ fill(tm,tm+20,inf); int i,j; for(i=0,j=0;i<10;i++) if(s>>i&1) tm[j++] = i; *lower_bound(tm,tm+20,d) = d; int news = 0; for(i=0;i<10;i++) if(tm[i]!=inf) news |= (1 << tm[i]); return news; } int cnt(int s){ int res = 0,i; for(i=0;i<10;i++) if(s>>i&1) res++; return res; } LL dfs(int i,int s,bool e,bool z){ if(i == -1) return cnt(s) == k ? 1LL : 0; if(!e&&dp[i][s][k] != -1) return dp[i][s][k]; LL res = 0; int d,u = e ? bit[i] : 9; for(d = 0 ; d <= u ; d++){ res += dfs(i-1,z&&(d==0) ? 0 : get_news(s,d),e&&(d==u),z&&(d==0)); } return e?res:dp[i][s][k]=res; } LL solve(LL n){ top = 0; for(;n;n/=10) bit[top++] = n%10; return dfs(top-1,0,1,1); } int main(){ int cas; scanf("%d",&cas); memset(dp,-1,sizeof(dp)); for(int T=1;T<=cas;T++){ scanf("%I64d%I64d%I64d",&l,&r,&k); printf("Case #%d: %I64d\n",T,solve(r)-solve(l-1)); } return 0; }
相关文章推荐
- hdu 1016
- 2015 国际冠军杯 深圳行
- Flume对Nginx群集日志收集方案
- HDOJ Number Sequence 1711【KMP裸题】
- C - How Many Tables - HDU-1213
- TI BLE开发(二)修改蓝牙连接参数
- css 圆角写法
- 关于正则表达式
- tomcat中文参数乱码
- ACM计算几何推荐
- 浅谈微信卡券功能开发(1)
- android 使用NDK
- flume、kafka、storm常用命令
- IndexedDB:浏览器里内置的数据库(转)
- [好文要转]【关于block使用的5点注意事项】
- select/**/*/**/from/**/RegSite
- Dynamic Programming - Part2
- KAFKA学习总结
- 深入理解kafka设计原理
- 什么是静态地址重定位,它需要什么支持?什么是动态地址重定位,他需要什么支持?静态地址重定位与动态地址重定位有什么区别?