POJ 3286 How many 0's? (数位dp)
2015-09-05 20:42
447 查看
题目:http://poj.org/problem?id=3286
题意:求n-m之间的数含有的0的个数。
思路:用数位dp记忆化搜索模版。
代码:
题意:求n-m之间的数含有的0的个数。
思路:用数位dp记忆化搜索模版。
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; typedef long long ll; int bit[70]; ll f[70][20][5]; ll dp(int pos, int sta, int flag, int str) { //printf("%d %d %d %d\n", pos, sta, flag, str); //第len到pos+1位已确定,现在要确定第pos位 //前面已经出现了sta个c //flag=1,不论第pos位为什么都比给定的数小 //str=1,第len到第pos+1位出现了不是0的数 if(pos == 0) return sta; if(flag && f[pos][sta][str] != -1) return f[pos][sta][str]; ll ans = 0; int x = flag ? 9 : bit[pos]; for(int i = 0; i <= x; i++) { if(i == 0) { if(str) ans += dp(pos - 1, sta + 1, flag || i < x, 1); else ans += dp(pos - 1, sta, flag || i < x, 0); } else { ans += dp(pos - 1, sta, flag || i < x, 1); } } if(flag) f[pos][sta][str] = ans; return ans; } ll cal(ll x) { if(x == -1) return -1; int len = 0; while(x) { bit[++len] = x % 10; x /= 10; } ll ans = dp(len, 0, 0, 0); //printf("---%I64d---\n", ans); return ans; } int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif ll m, n; memset(f, -1, sizeof(f)); while(scanf("%I64d %I64d", &m, &n) != EOF) { if(m < 0 && n < 0) break; //printf("m=%I64d n=%I64d\n", m, n); printf("%I64d\n", cal(n) - cal(m - 1)); } return 0; }
相关文章推荐
- LeetCode || Valid Number
- NSDate转成NSString的函数
- ç7—UIViewController
- [LinkerScript.5] 简单的链接器脚本命令: 文件命令 - Simple Linker Script Commands: File Commands
- get请求中文乱码,思考为什么要用两次的encodeURI()
- Android按钮单击事件的四种常用写法总结
- 那些逗比着赚钱的APP们
- Lowest Common Ancestor of a Binary Tree
- QQ聊天
- strace 工具
- Eclipse添加Android项目工程后res文件夹下layout/values/drawable文件不可见
- 在多线程/进程环境下,计算系统的总响应时间
- 六款值得推荐的android(安卓)开源框架简介
- 软工视频——软工概论
- Apache Camel的sample的简单示例
- Linux 命令[4]:pwd,date
- 日志文件名更新
- PHP博客
- java下管道流 PipedOutputStream 与PipedInputStream
- 摄影测量后方交会-前方交会(C#)