• hdu 5898 odd-even number(数位dp)


    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.

    题意:一个数中所有连续的奇数长度都为偶数,所有连续偶数的长度都为奇数。我们要找一个区间内一共有多少个这样的数。

    区间范围(1~9*10^18)所以显然是数位dp搞。设dp[len][count][temp],temp=1表示偶数,temp=2表示奇数,temp=0表示取首位0时,

    count表示到len位置有几个奇数或偶数个。显然简单的搜索,标准数位dp

    #include <iostream>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    ll dp[22][22][3];
    int dig[20];
    ll dfs(int len , int count , int temp , int flag , int first) {
        if(len == 0) {
            if(temp == 1) {
                if(count % 2 != 0) {
                    return 1;
                }
                else {
                    return 0;
                }
            }
            if(temp == 2) {
                if(count % 2 == 0) {
                    return 1;
                }
                else {
                    return 0;
                }
            }
            return 0;
        }
        if(!flag && !first && dp[len][count][temp] != -1) {
            return dp[len][count][temp];
        }
        int n = flag ? dig[len] : 9;
        ll sum = 0;
        for(int i = 0 ; i <= n ; i++) {
            if(first) {
                if(i == 0) {
                    sum += dfs(len - 1 , 0 , 0 , flag && i == n , first && i == 0);
                }
                else {
                    if(i % 2 == 0) {
                        sum += dfs(len - 1 , count + 1 , 1 , flag && i == n , first && i == 0);
                    }
                    else {
                        sum += dfs(len - 1 , count + 1 , 2 , flag && i == n , first && i == 0);
                    }
                }
            }
            else {
                if(i % 2 == 0) {
                    if(temp == 1) {
                        sum += dfs(len - 1 , count + 1 , 1 , flag && i == n , first && i == 0);
                    }
                    if(temp == 2) {
                        if(count % 2 == 0) {
                            sum += dfs(len - 1 , 1 , 1 , flag && i == n , first && i == 0);
                        }
                    }
                }
                else {
                    if(temp == 1) {
                        if(count % 2 != 0) {
                            sum += dfs(len - 1 , 1 , 2 , flag && i == n , first && i == 0);
                        }
                    }
                    if(temp == 2) {
                        sum += dfs(len - 1 , count + 1 , 2 , flag && i == n , first && i == 0);
                    }
                }
            }
        }
        if(!flag && !first) {
            dp[len][count][temp] = sum;
        }
        return sum;
    }
    ll Get(ll x) {
        int len = 0;
        memset(dp , -1 , sizeof(dp));
        memset(dig , 0 , sizeof(dig));
        if(x == 0)
            len = 1;
        while(x) {
            dig[++len] = x % 10;
            x /= 10;
        }
        return dfs(len , 0 , 0 , 1 , 1);
    }
    int main()
    {
        int t;
        cin >> t;
        int ans = 0;
        while(t--) {
            ans++;
            ll l , r , gg;
            cin >> l >> r;
            cout << "Case #" << ans << ": " << Get(r) - Get(l - 1) << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    销售排行榜
    视频合并的问题
    全排列的问题
    24点的游戏
    分数拆分
    竖式
    MVVM
    package
    WP8.1APP执行流程
    W
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6026156.html
Copyright © 2020-2023  润新知