1. 程式人生 > 實用技巧 >HDU 5898 odd-even number(數位dp)

HDU 5898 odd-even number(數位dp)

套路題,維護前面的奇偶性和長度

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
int s[N];
ll f[30][2][2][4][4];
int len;
ll dfs(int u,int sign,int g,int num,int flag){
    if(u==len+1){
        if((num%2)&&(flag%2)){
            return
0; } if((num%2==0)&&(flag%2==0)){ return 0; } return 1; } if(f[u][sign][g][num][flag]!=-1) return f[u][sign][g][num][flag]; int up; if(sign) up=s[u]; else up=9; int i; ll res=0; auto &x=f[u][sign][g][num][flag];
for(i=0;i<=up;i++){ if(g&&(i==0)){ res+=dfs(u+1,sign&&(i==up),g,1,0); continue; } if((num%2==0)&&(i%2==0)){ res+=dfs(u+1,sign&&(i==up),0,0,!flag); } if((num%2==0)&&(i%2)){ if(flag){ res
+=dfs(u+1,sign&&(i==up),0,1,1); } } if((num%2)&&(i%2==0)){ if(flag%2==0){ res+=dfs(u+1,sign&&(i==up),0,0,1); } } if((num%2)&&(i%2)){ res+=dfs(u+1,sign&&(i==up),0,1,!flag); } } return x=res; } ll get(ll x){ if(x==0) return 1; int cnt=0; while(x){ s[cnt++]=x%10; x/=10; } memset(f,-1,sizeof f); len=cnt-1; reverse(s,s+cnt); return dfs(0,1,1,1,0); } int main(){ ios::sync_with_stdio(false); int t; cin>>t; int cnt=0; while(t--){ ll l,r; cin>>l>>r; cout<<"Case #"<<++cnt<<": "; cout<<get(r)-get(l-1)<<endl; } return 0; }
View Code