hdu 5898 odd-even number (数位dp 沈阳网络赛)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5898
题意:

求l到r的数里面,有多少数符合奇数连续的数位长度是偶数,偶数连续的数位长度是奇数。

分析:

裸的数位dp

代码:

#include
using namespace std;
const int N=30;
typedef unsigned long long ll;
ll f[N][2][N];
// 数位、奇偶、长度
int bit[N];
//位置,前导是0,奇偶,奇偶的长度,当前序列是否符合条件,最大范围
ll dfs(int pos,int pre,int x,int length,int ok,bool lim) {
    if(pre&&!ok)return 0;
    if(pos==0)return (length+x)%2;

    if(!lim&&f[pos][x][length]!=-1)return f[pos][x][length];
    int num=lim?bit[pos]:9;
    ll ans=0;
    for(int i=0; i<=num; i++) {
        if(pre==0&&i==0)ans+=dfs(pos-1,0,0,0,1,0);
        else {
            if(pre==0)
                ans+=dfs(pos-1,1,i%2,1,1,lim&&(i==num));
            else {
                if(i%2==x)ans+=dfs(pos-1,1,x,length+1,ok ,lim&&(i==num));
                else ans+=dfs(pos-1,1,!x,1,ok&&(length+x)%2,lim&&(i==num));
            }
        }
    }
    if(!lim)f[pos][x][length]=ans;
    return ans;
}
ll solve(ll a) {
    int pos=0;
    while(a) {
        bit[++pos]=a%10;
        a/=10;
    }
    return dfs(pos,0,0,0,0,1);
}
int main() {
    //freopen("f.txt","r",stdin);
    int T;
    scanf("%d",&T);
    ll a,b;
    int cas=0;
    memset(f,-1,sizeof(f));
    while(T--) {
        scanf("%lld%lld",&a,&b);
        printf("Case #%d: %lld\n",++cas,solve(b)-solve(a-1));
    }
    return 0;
}
/*
Sample Input
2    
1 100    
110 220 

Sample Output
Case #1: 29
Case #2: 36
*/

你可能感兴趣的:(数位dp)