HDU 5787 K-wolf Number (数位DP)
K-wolf Number
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5787
Description
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].
Input
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
Output
For each test case output a line contains an integer.
Sample Input
1 1 2
20 100 5
Sample Output
1
72
Source
2016 Multi-University Training Contest 5
##题意:
找出区间[L,R]中有多少个数满足任意相邻的K位均不不相同.
##题解:
数位DP:分别对l-1.r求出从0开始一共有多少个数满足条件.
dp[i][j]:处理到还剩下i个数时左边相邻k个数是j(j代表一串数)的情况种数.
用map, LL> dp[maxn]来表示dp数组,vector存储左边相邻的k个数.
依次枚举每一位可能放置的数字并进行递归处理.
1. 在递归时要标记一下之前放置的那些数能否保证小于上限,如果可以当前位可以放置0-9任意数.
2. 注意处理前导零和非前导零的情况:这里用-1代表前导零,如果枚举到当前位为0时,要先看上一位是否为-1,如果是-1则当前位要更新为-1(也是前导零).
3. 记忆化:用map-dp记录下当前的计算结果. 注意:仅当当前数能确定比上限小时才能记录dp值.
(反例:比如样例的20和100,先处理100得到dp[2][-1,-1,-1]=91, 若记录下当前dp,在处理19时,则会直接返回91.)
4. 之前一直TLE是因为每次处理数据时都把dp初始化了一遍,而实际上对于所有数据dp都可以共用,只需要初始化一次即可.
5. 看到一份用五维dp数组记录的代码仅用了300ms,而上述用map-vector的记录方式用了2000ms.
##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define mid(a,b) ((a+b)>>1)
#define eps 1e-8
#define maxn 55000
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
int k;
int num[20];
map<vector, LL> dp[20];
bool is_ok(const vector& cur) {
int state = 0;
for(int i=0; i<k; i++) {
if(cur[i] == -1) continue;
if(state & (1<<cur[i])) return false;
else state |= (1<<cur[i]);
}
return true;
}
LL dfs(int len, vector cur, bool is_small) {
if(len == 0) return 1LL;
if(is_small && dp[len].count(cur)) return dp[len][cur];
int limits = is_small? 9:num[len];
vector<int> next; next.clear();
int sz = cur.size();
for(int i=1; i<sz; i++) {
next.push_back(cur[i]);
}
LL ret = 0;
for(int i=0; i<=limits; i++) {
if(i) next.push_back(i);
else {
if(next[k-2] == -1) next.push_back(-1);
else next.push_back(0);
}
if(is_ok(next)) {
ret += dfs(len-1, next, !(!is_small&&i==limits));
}
next.pop_back();
}
if(is_small) dp[len][cur] = ret;
return ret;
}
LL solve(LL x) {
int cnt = 0;
vector cur; cur.clear();
while(x) {
num[++cnt] = x % 10;
x /= 10;
}
for(int i=0; i<k; i++)
cur.push_back(-1);
return dfs(cnt, cur, 0);
}
int main(int argc, char const *argv[])
{
//IN;
LL l,r;
for(int i=0; i<20; i++) dp[i].clear();
while(scanf("%I64d %I64d %d", &l,&r,&k) != EOF)
{
//for(int i=0; i<20; i++) dp[i].clear();
printf("%I64d\n", solve(r) - solve(l-1));
}
return 0;
}
HDU 5787 K-wolf Number (数位DP)的更多相关文章
- 多校5 HDU5787 K-wolf Number 数位DP
// 多校5 HDU5787 K-wolf Number 数位DP // dp[pos][a][b][c][d][f] 当前在pos,前四个数分别是a b c d // f 用作标记,当现在枚举的数小 ...
- HDU.4352.XHXJ's LIS(数位DP 状压 LIS)
题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...
- HDU 5787 K-wolf Number 数位DP
K-wolf Number Problem Description Alice thinks an integer x is a K-wolf number, if every K adjacen ...
- hdu 5898 odd-even number 数位DP
传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...
- HDU 3709 Balanced Number (数位DP)
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- HDU 5179 beautiful number 数位dp
题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...
- hdu 5898 odd-even number(数位dp)
Problem Description For a number,if the length of continuous odd digits is even and the length of co ...
- HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛
题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...
- 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】
Valley Numer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
随机推荐
- IIS 无法打开页面,只能重启的问题
最终解决方案: 要变通解决此问题,启用 EnableAggressiveMemoryUsage 注册表项在注册表中.当启用了 EnableAggressiveMemoryUsage 注册表项 Http ...
- NFC(4)响应NFC设备时启动activity的四重过滤机制
响应NFC设备时启动activity的四重过滤机制 在一个NFC设备读取NFC标签或另一个NFC设备中的数据之前会在0.1秒之内建立NFC连接,然后数据会自动从被读取一端流向读取数据的一端(NFC设备 ...
- 【POJ】3134 Power Calculus
1. 题目描述给定一个正整数$n$,求经过多少次乘法或除法运算可以从$x$得到$x^n$?中间结果也是可以复用的. 2. 基本思路实际结果其实非常小,肯定不会超过20.因此,可以采用IDA*算法.注意 ...
- Android开发之LocationManager和定位
代码: /* * 获取当前的位置,并通过短信发送位置到指定号码 */ public class LocationService extends Service { private LocationMa ...
- IDEA 创建Web项目并在Tomcat中部署运行
IDEA 14.0.5 apache-tomcat-8.0.32 步骤:File->New Project,在Java列表中勾选Web Application(3.1),点击Next 建立web ...
- Jquery 弹出新窗体
开始先用css将这个DIV设好位置,并且隐藏 function winshow() { var winNode = $(".win"); winNode.show("sl ...
- 1085: [SCOI2005]骑士精神
A*搜索. A*搜索的基础百度百科(实在偷懒没看论文之类的),在这里不说了. A*搜索很关键的是h(n)估价函数的选取(表示现在到结束节点需要的距离) 设d(n)为实际到结束节点的距离.h(n)< ...
- UVa 12230 (期望) Crossing Rivers
题意: 从A到B两地相距D,之间有n段河,每段河有一条小船,船的位置以及方向随机分布,速度大小不变.每段河之间是陆地,而且在陆地上行走的速度为1.求从A到B的时间期望. 分析: 我们只要分析每段河的期 ...
- (转)Linux: su sudo sudoer
http://zebralinux.blog.51cto.com/8627088/1369301 日常操作中为了避免一些误操作,更加安全的管理系统,通常使用的用户身份都为普通用户,而非root.当需要 ...
- 使用ffmpeg向crtmpserver发布rtsp流
ffmpeg的调用命令如下: ffmpeg -re -i xxx.mp4 -vcodec copy -acodec copy -f rtsp rtsp://127.0.0.1/live/mystre ...