HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛

题目链接

题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的。问[L , R]的好数个数。

题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的值的奇偶性和长度奇偶性即可.

#include <iostream>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <queue>
using namespace std;
long long dp[25][2][25];
int bit[25];
long long dfs(int pos,int preTy,int prelen,bool flag) { //flag为true的话表示当前位触顶了
    if(pos==-1) {
        if(prelen%2 != preTy) return 1;
        else return 0;
    }
    if(!flag && dp[pos][preTy][prelen]!=-1) return dp[pos][preTy][prelen];
    int e = flag?bit[pos]:9;
    long long ans=0;
    for(int i=0;i<=e;i++) {
        if(prelen==0&&i==0) {
            ans += dfs(pos-1,1,0,flag&&i==e);
            //ans += dfs(pos-1,i%2,preTy==0?prelen+1:1,flag&&i==e);
        }
        else if(i%2==0) {
            if(preTy==1&&prelen%2==1) continue;
            ans += dfs(pos-1,0,preTy==0?prelen+1:1,flag&&i==e);
        }
        else {
            if(preTy==0&&prelen%2==0) continue;
            ans += dfs(pos-1,1,preTy==1?prelen+1:1,flag&&i==e);
        }
    }
    //printf("%d %d %d %d %d\n",pos,preTy,prelen,flag,ans);
    if(!flag) return dp[pos][preTy][prelen]=ans;
    return ans;
}

long long solve(long long n) {
    int pos=0;
    while(n) {
        bit[pos++] = n%10;
        n/=10;
    }
    memset(dp,-1,sizeof(dp));
    return dfs(pos-1,1,0,true);
}
int main() {
    int T;
    long long l,r;
    cin>>T;
    int kase=1;
    while(T--) {
        cin>>l>>r;
        printf("Case #%d: ",kase++);
        cout<<solve(r)-solve(l-1)<<endl;
        //cout<<solve(r)<<endl;
    }
}

 

posted @ 2016-09-19 18:35  Ritchie丶  阅读(254)  评论(0编辑  收藏  举报