数位DP--不要62

题目大意:求出给定区间内,不包含62 和 4 的数字的个数

思路在代码里面,细节蛮多的,注意一下

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 10;
int dp[MAXN][2];
//dp[i][0] 表示长度为i的任意数字中不含4 也不含62 的数字的个数
//dp[i][1] 表示长度为i的任意数字中不含 4  也不含62, 但是以2开头的数字的个数
int a,b;
void init()
{
	dp[0][0]=1;
	for(int i=1;i<MAXN;i++)
	{
		dp[i][0] = dp[i-1][0]*9-dp[i-1][1];	
		dp[i][1] = dp[i-1][0];
	}
}
int num[MAXN],len;
#define fuck printf("fuck\n");
int solve(int n)
{
	len=1;
	int temp = n;
	while(n)
	{
		num[len++]=n%10;
		n/=10;
	}
	num[len]=0;len--;
	int ans =0 ;
	for(int i=len;i;i--)
	{
		//不能使用数字4
		if(num[i]>4)ans +=dp[i-1][0]*(num[i]-1);
		else  ans += dp[i-1][0]*num[i];

		//如果当前位大于6,那么6可以和后一位的2开头的不包含62的数字组成一个62,所以要减去
		if(num[i]>6)ans -= dp[i-1][1];

		//如果符合下面条件,同上,注意减去的数字长度
		if(num[i+1]==6&&num[i]>2) {ans -= dp[i][1];}
		//printf("nun--%d  ans--%d\n",num[i],ans); 

		//如果数字本身出现了62或者4,那么就可以直接跳出了
		if(num[i+1]==6&&num[i]==2)break;
		if(num[i]==4)break;
	}
	//printf("num=%d ans=%d\n",temp,ans);
	return ans ;
}
#define bug3
void debug()
{
	for(int i=0;i<=3;i++)
	{
		for(int j=0;j<2;j++)
		{
			printf("dp[%d][%d]->%d\n",i,j,dp[i][j]);
		}
	}
}
int main()
{
	freopen("data.in","r",stdin);
	freopen("me.out","w",stdout);
	init();
	#ifdef bug
	debug();
	#endif
	while(scanf("%d%d",&a,&b)&&(a+b))
	{
		//printf("%d %d \n",a,b);
		printf("%d\n",solve(b+1)-solve(a));
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值