hdu2089

hdu2089 不要62
传送门

题意

计算区间\([n,m](0<n\leq m<1e6)\)中不包含62和4的数的个数

题解

数位\(dp\)
预处理\(n,m\)的数位,从高位到低位进行数位\(dp\)
\(dp[i][0]\)表示直到第\(i\)位,\(62\)\(4\)都没有出现,既不含\(62\)也不含\(4\)的数的个数。
\(dp[i][1]\)表示直到第\(i\)位,\(62\)\(4\)都没有出现,既不含\(62\)也不含\(4\),但是上一位是\(6\)的数的个数。
\(dp[i][2]\)表示直到第\(i\)位,\(62\)或者\(4\)出现过,既不含\(62\)也不含\(4\)的数的个数。

#include<bits/stdc++.h>
#define LL long long
#define PII pair<int,int>
using namespace std;

int n,m,bit[10],dp[10][3];

int dfs(int pos,int sta,bool limit){
	if(pos==-1) return sta!=2;
	if(!limit && dp[pos][sta]!=-1) return dp[pos][sta];
	int up=limit?bit[pos]:9;
	int ans=0;
    for(int i=0;i<=up;i++){
    	if(sta==2 || (sta==1 && i==2) || i==4){
    		ans+=dfs(pos-1,2,limit && i==up);
    	}
    	else if(i==6){
    		ans+=dfs(pos-1,1,limit && i==up);
    	}
    	else{
    		ans+=dfs(pos-1,0,limit && i==up);
    	}
    }
    if(!limit) dp[pos][sta]=ans;
    return ans;
}

int solve(int x){
	int cnt=0;
	while(x){
		bit[cnt++]=x%10;
		x/=10;
	}
	return dfs(cnt-1,0,1);
}

int main(){
	memset(dp,-1,sizeof(dp));
	while(scanf("%d %d",&n,&m)!=EOF && (n || m)){
		printf("%d\n",solve(m)-solve(n-1));
	}
}
posted @ 2020-07-14 18:34  fxq1304  阅读(25)  评论(0)    收藏  举报