HDU 5787 K-wolf Number 数位dp
2016-08-03 01:17
447 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5787K-wolf Number
Time Limit: 6000/3000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)问题描述
Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation of x is pairwised different.
Given (L,R,K), please count how many K-wolf numbers in range of [L,R].
输入
The input contains multiple test cases. There are about 10 test cases.
Each test case contains three integers L, R and K.
1≤L≤R≤1e18
2≤K≤5
输出
For each test case output a line contains an integer.
样例
sample input
1 1 2
20 100 5
sample output
1
72
题意
求L到R之间的所有的满足十进制表示中任意相邻的k位数字都不相同的数
题解
数位dp,注意处理下前导零。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<map> #define bug(x) cout<<#x<<" = "<<x<<endl; using namespace std; const int maxn = 20; typedef __int64 LL; //vector<int> 存放第i-k+1位到第i位的数 map<vector<int>, LL> dp[maxn]; int k; //判断第0到k-2是否与k-1相同 bool ok(const vector<int>& ve) { int last = ve[k - 1]; for (int i = 0; i < k - 1; i++) { if (last == ve[i]) return false; } return true; } int arr[maxn],tot; //ismax标记表示前驱是否是边界值,为true代表前驱都是边界值,为false则说明前驱已经小于边界了,这一位可以任意取了。 //iszer表示前驱是否都为0,即前面几位是否都为0 //vec记录的是前驱的结尾的k位 LL dfs(int len,vector<int> vec, bool ismax,bool iszer) { if (len == 0) { //递归边界,这说明前驱都合法了 return 1LL; } if (!ismax&&dp[len].count(vec)) return dp[len][vec]; LL res = 0; int ed = ismax ? arr[len] : 9; vector<int> ve; for (int i = 1; i < vec.size(); i++) { //这里吧前导零的部分贴成负数,防止当成真正的0来判。 if (iszer) ve.push_back(-i); else ve.push_back(vec[i]); } for (int i = 0; i <= ed; i++) { ve.push_back(i); if (ok(ve)) { res += dfs(len - 1, ve, ismax&&i == ed,iszer&&i==0); } ve.pop_back(); } return ismax ? res : dp[len][vec] = res; } LL solve(LL x) { tot = 0; while (x) { arr[++tot] = x % 10; x /= 10; } vector<int> vec; for (int i = 1; i <= k; i++) vec.push_back(-i); return dfs(tot, vec, true,true); } void init() { for (int i = 0; i < maxn; i++) dp[i].clear(); } int main() { LL x, y; init(); while (scanf("%I64d%I64d%d",&x,&y,&k)==3) { printf("%I64d\n", solve(y)-solve(x-1)); } return 0; }
相关文章推荐
- 哈夫曼树的建立以及哈夫曼编码
- Mac搭建Apache+PHP+MySQL环境
- 邻接矩阵实现prim算法
- Angular Service和Fatory的差异
- Android官方文档之Location and Sensors APIs(上)
- JHTP自测题_第十三章_图形及Java2D
- Android中TextView不能识别电信号码11888的问题。
- 自定义Dom4j类库
- 理解抽象类和接口的区别 ---- 是不是 和 有没有 --- 的区别
- 解决eclipse配置Tomcat时找不到server选项
- 邻接矩阵实现克鲁斯卡尔算法
- POJ 2387 Til the Cows Come Home
- springMVC------Rest风格,HiddenHttpMethodFilter的作用
- 关联Tomcat服务器
- mysql的基本命令
- 在二叉树中找出和为某一值的所有路径
- iOS 从Objective-C到Swift
- Swing是一把刀(转载)
- Logging separation
- linux权限管理