我滴头啊~晕啊晕。这题终于让我把数位DP的本质看清楚了。

http://acm.fzu.edu.cn/problem.php?pid=2109

题目

Problem DescriptionOne integer number x is called "Mountain Number" if:(1) x>0 and x is an integer;(2) Assume x=a[0]a[1]...a[len-2]a[len-1](0≤a[i]≤9, a[0] is positive). Any a[2i+1] is larger or equal to a[2i] and a[2i+2](if exists).For example, 111, 132, 893, 7 are "Mountain Number" while 123, 10, 76889 are not "Mountain Number".Now you are given L and R, how many "Mountain Number" can be found between L and R (inclusive) ?InputThe first line of the input contains an integer T (T≤100), indicating the number of test cases.Then T cases, for any case, only two integers L and R (1≤L≤R≤1,000,000,000).OutputFor each test case, output the number of "Mountain Number" between L and R in a single line.Sample Input3
1 10
1 100
1 1000Sample Output9
54
384

题意:给一对区间[l,r],让你求闭区间内Mountain数的个数。

Mountain数的定义:给你一个数a0a1a2a3...an,ai代表当前位的数字,任一奇数位的数比身旁偶数位的个数大,这即是Mountain数。

做法:数位dp之记忆化搜索

首先,我们先搞明白dp数组到底是干嘛用的,其实它是记录当前数位的状态(这个状态通常跟前面的数位有关)下能够推出多少种符合的情况,也就是说dp数组是承前启后的,记忆化搜索本质就是递归求解树,求这棵大树从根到叶子节点能够找到多少条符合的路径。假如dp数组是三维的,我们定义它为dp[a][b][c],记忆化搜索的时间复杂度为O(a*b*c)。

对于本题,我们定义dp数组为dp[pos][pre][parity],pos表示当前的位置,pre表示前一位的数字,parity表示,从无前导0的数字到下一状态位的奇偶性(注意数字是从a0开始的),奇数为1,偶数为0。

下面我们开始构造DFS函数:

一、确定参数:

1、首先是万年不变的pos,代表当前要算哪一位

2、然后是寻常见的pre,代表前一位的数字

3、parity,从没有前导0开始到下一状态的奇偶性

4、jud,是否算到了没有前导0的数位,

5、doing,是否到达上界

二、函数结构化的写法

1、万年不变,if(pos==-1) {怎么怎么滴}//不是return 1就是0

2、万年不变:if(!doing&&dp[][][]!=-1) return dp[][][];

3、确定边界end

4、for(i=0;i<=end;++i),符合条件的,则ans+=dfs()

5、如果当前没有到达上届,则把ans的值赋给dp[][][]

6、return ans

三、什么时候ans需要加上dfs()的状态下符合数的个数呢

1、当前位置仍然是前导0的情况下,我们还需要加,但是别忘了给pre定义为9,这样当它遇到非前导0的数位时,不会判断出错

2、当前位置已经不是前导0了(前面有非0的数字),当前位置是奇性的,下一位置等于或者小余这个位置的数字

3、当前位置已经不是前导0了(前面有非0的数字),当前位置是偶性的,下一位置等于或者大于这个位置的数字

然后我个人觉得cal函数不值一提,就不详细的写了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[12][10][2],digit[12];
int dfs(int pos , int pre,int parity,bool jud,bool doing) //doing为边界,pos为计算到当前第几位
{if(pos==-1) return 1;if(!doing&&dp[pos][pre][parity]!=-1)return dp[pos][pre][parity];int ans=0,end;end=doing?digit[pos]:9;for(int i=0;i<=end;++i){/*jud表示前面有无前导0,pre参数必须为9啊,否则当它遇到第一个不是前导0的数字时,就判断出错了。那时候parity=0,必须使得pre>=i,*/if(!(jud||i)) ans+=dfs(pos-1,9,0,jud||i,doing&&i==end); //如果此位仍然为前导0else if(parity&&pre<=i)  //如果下一状态为奇性的ans+=dfs(pos-1,i,parity^1,jud||i,doing&&i==end);else if(!parity&&pre>=i) //如果下一状态为偶性的ans+=dfs(pos-1,i,parity^1,jud||i,doing&&i==end);}if(!doing)dp[pos][pre][parity]=ans;return ans;
}
int cal(int x)
{int pos = 0;while(x){digit[pos++] = x % 10;x /= 10;}return dfs(pos-1,9,0,0,1); //9很重要~~
}
int main()
{int t,l,r;cin>>t;memset(dp,-1,sizeof(dp));while(t--){cin>>l>>r;printf("%d\n",cal(r)-cal(l-1));}
}

转载于:https://www.cnblogs.com/A-way/archive/2013/04/17/3027161.html

FZU_2019_Mountain Number题解相关推荐

  1. Problem 2. number题解

    number:数学+二分图匹配 首先,如果S<N,那么S+1,S+2...N这些数直接放在S+1,S+2...N的位置上(如果其他数x放在这些位置上面,这些数不放在对应位置,那么x一定能放在这些 ...

  2. UVA10909 Lucky Number题解

    原文链接:http://www.algorithmist.com/index.php/User:Sweepline/UVa_10909.cpp AC的C++语言程序: /** Solution for ...

  3. 第11期《codeforces 1167A - Telephone Number 题解 》

    题目描述如下: A. Telephone Number time limit per test 1 second memory limit per test 256 megabytes input s ...

  4. [CF55D]Beautiful Number 题解

    数位dp进阶题. 如果一个数能被它的所有数位整除,那么他一定可以被那些数位的\(LCM\)整除. 发现\(1-9\)的\(LCM\)是\(2520\),所以这些数位的\(LCM\)一定是\(2520\ ...

  5. 2015浙江财经大学ACM有奖周赛(一) 题解报告

    2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...

  6. Valid Number

    Valid Number 题解 题目描述 即判断某个字符串是否合法的数字表达式. 如: 2e10,合法. 75.0.,非法. 0e,非法. 0.1 ,合法. 题解 基于规则与状态判断.可利用二维数组模 ...

  7. 2019 ICPC中国邀请赛(南昌)暨国际丝绸之路程序设计竞赛-网络赛题解

    以下所有AC题解程序来自"仙客传奇"团队. AC题数:10/13 ABCDHIJKLM A. PERFECT NUMBER PROBLEM 解题思路:先编写离线程序计算出最小的5个 ...

  8. 莫队算法(普通莫队、带修莫队、树上莫队、不删除莫队)学习笔记【理解+套路/核心代码+例题及题解】

    一.理解 我的理解就是巧妙的暴力,利用双指针以及分块思想,巧妙的移动双指针,时间复杂度可以达到O(NlogN). 强推博客:写的又好又全.链接 二.套路 1.普通莫队 [1]核心代码 bool cmp ...

  9. python回溯算法_什么是回溯法,Python解法交流?

    只有去多做题,才能慢慢掌握.力扣​leetcode-cn.com LeetCode 上的解释 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就 ...

最新文章

  1. YOLO算法史上最全综述:从YOLOv1到YOLOv5
  2. 【BZOJ】3052: [wc2013]糖果公园 树分块+带修改莫队算法
  3. 流量治理神器-Sentinel限流熔断应用实战
  4. 小程序的发布并发布为Android App流程
  5. 信息论实验-信源编码算法 (Huffman and Shannonn Fano编码C++实现)
  6. google 常用的技术搜索关键词
  7. Mybatis Generator(简称MBG)的最完整配置文件详解
  8. 【python】OpenCV—Video to Imag / Image to Video
  9. Python 机器学习 | 超参数优化 黑盒(Black-Box)非凸优化技术实践
  10. arduino中的serial .available()和serial.read()是区别
  11. Unity-3D游戏开发套件指南(入门篇)-免费资源
  12. 蒂娜交易准则(黄金高胜算交易)
  13. DCDC知识总结整理
  14. Android Camera基本用法一
  15. Python学习之封装、继承、多态详解
  16. 安卓自定义View进阶-事件分发机制原理【转自 app架构师 微信公众号】
  17. QN – 全能看图插件
  18. 不只中国消费者嫌iPhone贵,美国用户也更爱便宜的iPhone11
  19. 自考计算机微型计算机阶段储存系统,自考《微型计算机及其接口技术》学习方法(1)...
  20. ubuntu 安装飞鸽传书

热门文章

  1. json接口文档模板_在.Net Core WebAPI下给Swagger增加导出离线文档功能
  2. win centos php语法,linux(centos5.5)/windows下nginx开启phpinfo模式功能的配置方法分享
  3. centos 5.8 mysql_linux centos5.8装yum安装mysql
  4. 字典 选取前100_100道 Python 经典练习题004
  5. saltstack python3安装_如何在linux下升级python以及saltstack安装
  6. 网站点赞 评论 回复 数据库设计
  7. 如何用互联网思维搞定零售业
  8. 权重确定方法之主成分分析法
  9. java开发windows应用_Java开发在生活中实际的应用有哪些?
  10. Linux 常见命令操作(杀死全部screen)