hdu5898 odd-even number(数位dp)

来源:互联网 发布:python for循环遍历 编辑:程序博客网 时间:2024/04/30 05:11

odd-even number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description
For a number,if the length of continuous odd digits is even and the length of continuous even digits is odd,we call it odd-even number.Now we want to know the amount of odd-even number between L,R(1<=L<=R<= 9*10^18).

Input
First line a t,then t cases.every line contains two integers L and R.

Output
Print the output for each case on one line in the format as shown below.

Sample Input

2
1 100
110 220

Sample Output

Case #1: 29
Case #2: 36

题解:
觉得自己对数位dp的理解还不够透彻,尤其是对于数位dp的前导0的处理,这道题自己就是没有很好的方法处理前导0。
首先我第一个难点是觉得开始的判断没有办法处理,比如123,在1之前我是不能判断的,因为1之前没有数字。
对于前导0的判断我们需要加一个标志,最后计算结果的时候我们也要忽略前导0。
如果当前数字和前一个数字的奇偶性不同,那么就开始判断Len,如果当前是前导0的话,我们就不要判断,而且前导0是不能算在偶数内的。

#include<bits/stdc++.h>using namespace std;int a[20];//连续的奇数有偶数个 连续的偶数有奇数个long long dp[20][20][2];long long dfs(int pos,bool iszero,int L,int is,int lim) {    if(pos<0)        return (!iszero)&&((L&1)!=(is&1));    if((~dp[pos][L][is])&&(!lim))        return dp[pos][L][is];    int len=lim?a[pos]:9;    long long ans=0;    for(int i=0; i<=len; ++i) {        if(iszero) {            if(!i) {                ans+=dfs(pos-1,true,0,0,lim&&(i==len));            } else {                ans+=dfs(pos-1,false,1,i&1,lim&&(i==len));            }        } else {            if(is&1) {                if(i&1)ans+=dfs(pos-1,false,L+1,i&1,lim&&(i==len));                else {                    if(L%2==0)                        ans+=dfs(pos-1,false,1,i&1,lim&&(i==len));                }            } else {                if(i&1) {                    if(L&1)                        ans+=dfs(pos-1,false,1,i&1,lim&&(i==len));                } else {                    ans+=dfs(pos-1,false,L+1,i&1,lim&&(i==len));                }            }        }    }    if(!lim)        dp[pos][L][is]=ans;    return ans;}long long solve(long long nums) {    int len=0;    while(nums) {        a[len++]=nums%10;        nums/=10;    }    return dfs(len-1,1,0,0,1);}int main() {    long long L,R;    int T,coun=0;    scanf("%d",&T);    memset(dp,-1,sizeof(dp));    while(T--) {        scanf("%lld%lld",&L,&R);        long long ans=solve(R)-solve(L-1);        printf("Case #%d: %lld\n",++coun,ans);    }    return 0;}
1 0