题目链接: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;
}