FZU2109(数位DP)
来源:互联网 发布:slam算法工程师 薪资 编辑:程序博客网 时间:2024/05/19 18:39
题目的意思就是给出一个范围.问这个范围内有几个数 满足奇数位上的数,都比左右两边大.
我们要一位位判断,直到整个数结束.
我们拿0-34567这个范围来举例.
这里有两个不好理解的标志位.
首先我们要考虑的是前导0问题.(也就是最开始会出现很多不必要的0 ,因为564是符合条件的,但是我们表示时是00564 ,直到5这一位才算是开始了,所以5才是第0位)
首先我们要有个标志位,标记前面是不是全是前导0, 如果前面全是,并且我们要算的这一位还是0,那么接下去就还是按全是前导0来算.
只要出现一位不是0了,那就永远不是前导0,就算填的是0,它也不是前导0;
还有一个标志就是 前面几位是不是达到最大值..比如你第一位是3 ,第二位是4 ,那么第三位只能选择填充0到5 ,如果再大,就超过最大值了.但是如果你前面没有达到最大.前两位填了33那么接下去所有位数,都可以填到9,也不会超过最大值. 那么判断接下去是不是还有达到最大,要满足两个,第一前面达到最大,并且当前填充的这个数字仍然是最大.
解决了这两个标志位,就可以开始dp了.
如果这一位是奇数位,且填的数大于前面,就可以继续.或者这一位是偶数位,且填的数小于前面.
知道所有位数填充完了,返回成功了一个,最后计算成功了几个.
但如果直接不断递归,会超时.所以我们利用dp的记忆化搜索.
d[pos][num][odd] pos代表当前是第几位了,num代表前一个数字是几,odd代表是奇数还是偶数..
首先你只到当前是第几位,也就是知道还剩下多少位要填,知道num,就知道当前要填数要和那个数字比较,当然还有奇偶行.
那是不是当这三个条件固定了,那么在这种情况下有几种可能是不是也固定了?
不一定,因为如果前面的值没打到最大,那么当前这位可以填0-9,那么没问题.
但是如果前面已经达到最大值了..那么当前这位就不能填0-9了,而是填0到这个数的最大值.
那么就不是唯一确定的值,就不能记忆化搜索(结果可能和你记录的不一样.)
为了避免.我们就只在前面没有达到最大值时,才采用记忆化搜索.
AC代码:
#include<stdio.h>#include<string.h>int d[12][12][2];int diet[12];int dfs(int pos , int pre0 , int isodd , int num , int s) {if(pos == -1)return 1;if(!s && d[pos][num][isodd] != -1)return d[pos][num][isodd];int upper = s ? diet[pos] : 9;int ans = 0;for (int i = 0 ; i <= upper ; i++) {if (i == 0 && pre0) {ans += dfs(pos - 1 , 1 ,isodd , 9 , 0);}else if(isodd && i <= num)ans += dfs(pos - 1 , 0 , isodd ^ 1 , i , s && (i == upper));else if(!isodd && i >= num)ans += dfs(pos - 1 , 0 , isodd ^ 1 , i , s && (i == upper));}if(!s)d[pos][num][isodd] = ans;return ans;}int cul(int x) {int pos = 0;while(x) {diet[pos++] = x % 10;x /= 10;}return dfs(pos - 1 , 1 , 1 , 9 , 1);}int main () {int t ; int l,r;scanf("%d",&t);memset(d , -1 ,sizeof(d));while(t--) {scanf("%d%d",&l,&r);printf("%d\n",cul(r) - cul(l - 1));}}
- FZU2109数位DP
- FZU2109(数位DP)
- FZU2109(数位dp)
- FZU2109:Mountain Number(数位DP)
- FZU2109:Mountain Number(数位DP)
- FZU2109 Mountain Number (数位DP)
- 【数位DP】模板+入门题HDU2089 FZU2109
- 数位dp
- 数位DP
- 数位DP
- 数位dp
- 数位dp
- 数位dp
- 数位DP
- 数位dp
- 数位DP
- 【数位DP】
- 数位DP
- SQL server 2008数据库的备份与还原(转)
- c++ 计时函数的使用
- Double check 双重锁检查
- DB2 alter表字段
- 关于Exception的那些事
- FZU2109(数位DP)
- Linux内核调试理清函数调用
- cpanm让Perl模块安装更EASY
- 2048游戏java版
- unity之数组总结和类的总结
- [leetcode]Find Minimum in Rotated Sorted ArrayII
- 测试
- UVa 11059 - Maximum Product
- 作业调度小软件