数位DP 不要62

数位DP的问法是从某个数到某个数的区间里,求出满足题目要求的个数;

如本题所说的不要62和4,就是求出这个区间内,满足这一条件的数;

比如问 6 199的这个区间内满足条件的数,那么就求出1到199满足的数减去1到(6-1)满足的数即可;

那么 具体怎么从操作呢?

首先,我们先求出这个数的a[]数组,求出每一位具体是什么数(dfs的时候需要用到)

然后开始dfs,从最高位开始逐步深搜下来,将不满足的情况过滤掉,然后将满足普遍情况的值保存下来

那么哪些是普遍情况呢:就是无论不会被限制条件限制掉的状态的数

最后枚举到最低位-1,再层层回溯就好了,

本题中的体现形式是:!limit

 1 #include<cstdio>
 2 #include<string.h>
 3 using namespace std;
 4 const int maxn=10;
 5 int dp[maxn][2],a[maxn];
 6 int dfs(int pos,int pre,int sta,bool limit)
 7 {
 8     if(pos==-1) return 1;   //枚举到比最低为少一位的时候,就开始回溯
 9     if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];  //满足普遍情况的就可以直接用
10                             //这是十分必要的,没有这一步的话跟普通dfs没什么区别
11     int up=limit?a[pos]:9;  //保存这个数的每一位的作用就体现在这里了
12                             //假如这一位数是5,那么他枚举的数便不能超过这个数
13     int tmp=0;
14     for(int i=0;i<=up;i++){
15         if(i==4) continue;
16         if(pre==6&&i==2) continue; //不满足的情况就过滤;
17         tmp+=dfs(pos-1,i,i==6,limit&&i==a[pos]);
18     }
19     if(!limit) dp[pos][sta]=tmp;  //满足普遍情况就保存;
20     return tmp;
21 }
22 int solve(int n)
23 {
24     int pos=0;
25     while(n){
26         a[pos++]=n%10;   //将这个数每一位的数保存下来;
27         n/=10;
28     }
29     return dfs(pos-1,-1,0,true);
30 }
31 int main()
32 {
33     int n,m;
34     memset(dp,-1,sizeof(dp));
35     while(scanf("%d%d",&n,&m)!=EOF){
36         if(m==0&&n==0) break;
37         printf("%d\n",solve(m)-solve(n-1));
38     }
39     return 0;
40 }

原文地址:https://www.cnblogs.com/pangbi/p/11877079.html

时间: 2024-10-24 19:50:14

数位DP 不要62的相关文章

[动态规划][数位dp]不要62

Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众.不吉利的数字为所有含有4或62的号码.例如:62315 73418 88914都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列.你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多

10.16复习 数位DP——不要62

Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众. 不吉利的数字为所有含有4或62的号码.例如: 62315 73418 88914 都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列. 你的任务是,对于每次给出的一个牌照区间号,推断出交管局今后又要实际上给多少辆新

HDU 2089 数位dp入门

开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> #include<queue> using namespace std; int n,m; /

HDU 2089 不要62(数位dp)

题意:给定一个区间[n, m],求这个区间当中不含62和4的个数.例如62315,88914就是不符合条件的. 数位dp第一题,dp[i][j]表示以 j 开头的 i 位数满足条件的个数,先要预处理出来所有的情况, 下面是预处理的核心.其中k表示j后面的那一位.max_len是题目中给的n的最大位数,这里是7,第二层for是枚举第max_len - i位的值. for (int i = 1; i <= max_len; i++) { for (int j = 0; j <= 9; j++) {

【ACM】不要62 (数位DP)

题目:http://acm.acmcoder.com/showproblem.php?pid=2089 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众.不吉利的数字为所有含有4或62的号码.例如:62315 73418 88914都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列.你的任务

hdu 2089 不要62 (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 思路:用变量记录吉利数,和最高位为2的吉利数还有不是吉利数的个数... code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[10][3]; //dp[i][j] ,i表示位数,j表示状态<pre name="code"

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

HDU2089 不要62[数位DP]

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 36862    Accepted Submission(s): 13418 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可