HDU - 5898

题目链接:HDU - 5898


显然我们可以数位dp,然后每一位的状态只和当前位的奇偶性,当前是否合法,当前奇偶数的个数的奇偶性。

注意前导零的影响。然后转移即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=22;
int dp[N][3][3][2],a[N],l,r,ts;
int dfs(int pos,int odd,int num,int ok,int zero,int lim){
	if(!pos)	return (ok&&(odd!=num));
	if(!zero&&!lim&&dp[pos][odd][num][ok]!=-1) return dp[pos][odd][num][ok];
	int up=lim?a[pos]:9,res=0;
	for(int i=0;i<=up;i++){
		if(zero&&!i) res+=dfs(pos-1,2,2,1,1,lim&&i==up);
		else{
			if(odd==2) res+=dfs(pos-1,i%2,1,1,0,lim&&i==up);
			else{
				if(odd==i%2) res+=dfs(pos-1,odd,num^1,ok,0,lim&&i==up);
				else res+=dfs(pos-1,i%2,1,ok&&(num!=odd),0,lim&&i==up);
			} 
		}
	}
	if(!zero&&!lim) dp[pos][odd][num][ok]=res;
	return res;
}
inline int calc(int x){
	int pos=0;
	while(x)	a[++pos]=x%10,x/=10;
	return dfs(pos,2,2,1,1,1);
}
void solve(){
	cin>>l>>r;
	printf("Case #%lld: %lld\n",++ts,calc(r)-calc(l-1));	
}
signed main(){
	memset(dp,-1,sizeof dp);
	int T; cin>>T; while(T--) solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/107804667
hdu