Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 57769 Accepted Submission(s): 22658 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
Input 输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
Output 对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
Sample Input 1 100 0 0
Sample Output 80
Author qianneng
Source
Recommend lcy | We have carefully selected several similar problems for you: 2094 2090 2091 2093 2092
|
入门级的数位dp题目,虽然我也是刚刚入门的,但是感觉网上大神的题解还是很好理解的
推荐一篇题解吧,特好:https://blog.csdn.net/wust_zzwh/article/details/52100392
思路:
大神的博客写的很详细了,这里就写一下在这个题目上对于大神代码的理解吧
首先的话,dfs枚举数,每一个数;
dfs中的变量:pos记录的当前的数位,也就是当前位上的数,
pre:这个的话,就是保存一下前面的数,不要62的话,当然要有前一个和现一个的判断,
sta:保存的就是前一位是否为6,如果前一位为6则这一位就不能是2;
limit:看一下现在枚举数位的后面是不是需要有枚举的限制,比如231如果上一位枚举到2,则这一位只能枚举到3,
其他的写在代码里面:
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
int a[22];
int dp[22][2];
int dfs(int pos,int pre,int sta,bool limit)
{
if(pos==-1) return 1; //数位到-1就代表这个数枚举完了
if(!limit&&dp[pos][sta]!=-1)
return dp[pos][sta]; //上一个数位没有枚举到最后这一个数枚举过了就不需要枚举了
int up=limit ? a[pos] : 9;//枚举数位取值
int tmp=0;
for(int i=0;i<=up;i++)
{
if(pre==6&&i==2)
continue;
if(i==4)
continue;//保证数据是合法的
tmp+=dfs(pos-1,i,i==6,limit&&i==a[pos]);
}
if(!limit) dp[pos][sta]=tmp;
return tmp;
}
int solve(int x)
{
int pos=0;
while(x)
{
a[pos++]=x%10;
x/=10;
}
return dfs(pos-1,-1,0,true);
}
int main()
{
int le,ri;
while(cin>>le>>ri&&le+ri)
{
memset(dp,-1,sizeof dp);
cout<<solve(ri)-solve(le-1)<<endl;
}
return 0;
}