# [hdu2089]不要62 题解

[hdu2089]不要62 题解

鸽的有点久了

某蒟蒻开始学计数dp了

思路

\(f_{i,1/0}\) 为前i个数位,前一位是否为 \(6\) 的合法数量

然后用dfs考虑每一个数位的取值,注意不要超过 \(R\) 上限

其中用一下记忆化

区间用前缀和求解

code

有点弱智偏xxs的马蜂

#include<bits/stdc++.h>
#define int long long
using namespace std;
int f[10][2];//f[i][j]:前i个数位,前一位是不是6 
int l,r,a[10];//a数组存R的上限,即各位数字 
//目前是第x位,v6判断前一位是否是6,pd判断是否为上界 
int dfs(int x,bool v6,bool pd)
{
	if(!x) return 1;//选完了,这个数可以,计算答案贡献 
	if(!pd&&f[x][v6]>-1) return f[x][v6];//记忆化 
	int lim=pd?a[x]:9;//判断上界,如果这一位前面的都是上界,那么这一位不能超过R的这一位 
	int ans=0;
	for(int i=0;i<=lim;i++)
	{
		if(i==4||(v6&&i==2)) continue;//不符合条件,即有62或4 
		ans+=dfs(x-1,i==6,pd&&(i==a[x]));
	}
	if(!pd) f[x][v6]=ans;
	return ans;
}
int solve(int R)//处理上限,然后计算答案 
{
	int cnt=0;
	while(R)
	{
		a[++cnt]=R%10;
		R/=10;
	}
	return dfs(cnt,0,1);
}
signed main()
{
	ios::sync_with_stdio(0);cin.tie(0);
	while(cin>>l>>r)
	{
		if(!l&!r) exit(0);
		memset(f,-1,sizeof f);
		cout<<solve(r)-solve(l-1)<<"\n";
	}
}
posted @ 2023-12-14 15:17  inlinexhx  阅读(4)  评论(0编辑  收藏  举报