HDU 3555 浅谈数位动态规划逆向计数问题练习
2017-09-22 17:27
691 查看
世界真的很大
学了一小会儿数位DP,自然要找一点题来练
还是要融汇贯通才好
找到新题与原题之间的联系,辅助解题
看题先:
description:
题意就是找0到n有多少个数中含有49。数据范围接近10^20
input:
第一行一个整数T 接下来T行,每行一个整数n
output:
T行。 每行一个整数表示答案
这道题
首先dfs转移里面,需要包含前面出没出现49,上一位是什么
要考虑出没出现49,出现了几次49。。
头大。。
可能是我蠢吧
然后灵光一现,出现了49不就是总数减去没有出现49吗
这个思路类比:BZOJ 3556
然后嘛,至于求没有出现49的数,只需要保证在任何时候都不出现49就行了
这个类比 HDU 2089
这个写起来就很简单了
只需要存一下上一位是什么就行了
完整代码:
#include<stdio.h> #include<cstring> #include<iostream> using namespace std; typedef long long dnt; dnt f[20][20]; int a[20],T; dnt dfs(int pos,int pre,int lim) { dnt ans=0; if(pos==-1) return 1; if(!lim && f[pos][pre]!=-1) return f[pos][pre]; int up=lim ? a[pos] : 9; for(int i=0;i<=up;i++) { if(pre==4 && i==9) continue; ans+=dfs(pos-1,i,lim && i==up); } if(!lim) f[pos][pre]=ans; return ans; } dnt solve(dnt n) { int cnt=0; dnt tmp=n; memset(a,0,sizeof(a)); while(n) { a[cnt++]=n%10; n/=10; } return tmp+1-dfs(cnt-1,0,1); } int main() { scanf("%d",&T); memset(f,-1,sizeof(f)); while(T--) { dnt n; cin >> n; cout << solve(n) << endl; } return 0; } /* EL PSY CONGROO */
嗯,就是这样
相关文章推荐
- 数位动态规划(acm hdu 3555 ,hdu 2089,hdu 4278)
- HDU 3652 浅谈数位动态规划朝花夕拾Ver2.0
- 【浅谈数位计数一类问题】
- HDU 4734 浅谈数位动态规划进阶
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- HDU 3555 Bomb [数位DP]【动态规划】
- HDU 3652 浅谈数位动态规划即记忆化搜索
- hdu 5410 CRB and His Birthday(动态规划,背包问题)
- hdu 4722(动态规划-数位dp)
- hdu 2841 Visible Trees(计数问题)
- 动态规划----计数问题
- 数位统计 sgu 390 <浅谈数位类问题>
- 8月22号的练习:HDU 1196&&HDU 1673&&HDU 1269&&HDU 1841(KMP)&&HDU 1176(数塔问题)
- HDU3555——Bomb(数位dp入门)
- HDU 3555 Bomb (数位dp)
- hdu 3555(数位dp裸题)
- HDU 3555 Bomb 数位dp
- hdu 3555(数位dp 入门)
- 动态规划,背包问题,卡题(CRB and His Birthday,HDU 5410)
- HDU 3555(数位dp)