zoukankan      html  css  js  c++  java
  • HDU 5898 odd-even number(2016沈阳网络选拔赛 数位DP)

      定义DP[pos][pre][odd][even],pos代表当前数位,pre代表前一位的数值,odd代表到前一位连续的奇数个数,even代表到前一位连续偶数个数。

      odd和even肯定至少有一个为0,而且最后的判断只和odd与even的奇偶性有关,能看出这个状态是可以被缩小到很小的,但是DP菜鸟我为了避免出错,还是定义了8万的可以接受的数组。

      代码及注释如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define LL long long
    LL dp[20][10][20][20];
    int bit[20];
    LL dfs(int pos,int pre,bool limit,bool lead0,int odd,int even)
    {
        if(pos == -1)
        {
            if(odd==0 && even%2==1) return 1;
            if(even==0 && odd%2==0) return 1;
            return 0;
        }
        if(!limit && !lead0 && dp[pos][pre][odd][even]!=-1)///为了
        ///保证没有任何的歧义,前两个判定条件是必要的
        {
            return dp[pos][pre][odd][even];
        }
        int up = limit? bit[pos]: 9;
        LL ans = 0;
        for(int i = 0; i <= up; i++)
        {
            bool Nlimit = (limit && i==up);
            bool Nlead0 = (lead0 && i==0);
            if(lead0)///前导0存在的时候,建议特殊判断
            {
                if(i==0) ans += dfs(pos-1,i,Nlimit,Nlead0,0,0);
                else if(i%2==0) ans += dfs(pos-1,i,Nlimit,Nlead0,0,1);
                else ans += dfs(pos-1,i,Nlimit,Nlead0,1,0);
            }
            else
            {
                if( (odd%2==1&&i%2==0) || (even!=0&&even%2==0&&i%2==1) ) continue;
                ///这两种状态是不符合要求的状态,第二个判断需要注意even = 0的情况
                if(i%2==0) ans += dfs(pos-1,i,Nlimit,Nlead0,0,even+1);
                else ans += dfs(pos-1,i,Nlimit,Nlead0,odd+1,0);
            }
        }
        if(!limit && !lead0) dp[pos][pre][odd][even] = ans;
        return ans;
    }
    LL solve(LL x)
    {
        int pos = 0;
        while(x)
        {
            bit[pos++] = x%10;
            x /= 10;
        }
        return dfs(pos-1,-1,true,true,0,0);
    }
    int main()
    {
    //    freopen("1.in.cpp","r",stdin);
        int t,ca=0;
        LL l,r;
        cin>>t;
        memset(dp,-1,sizeof(dp));
        while(t--)
        {
            cin>>l>>r;
            printf("Case #%d: ",++ca);
            cout<<solve(r)-solve(l-1)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    UIScrollView(滚动视图)
    NSJSONSerialization(json序列化)
    手势(UIGestureRecognizer)
    mac常用命令
    ios设备相关
    UITextField
    cocos2d学习笔记
    NSTimer(定时器)
    git命令
    Java 线程的终止-interrupt
  • 原文地址:https://www.cnblogs.com/jifahu/p/5933696.html
Copyright © 2011-2022 走看看