• SPOJ 10606. Balanced Numbers (数位DP)


    题目链接:http://www.spoj.com/problems/BALNUM/

    这题要求出现的数字,偶数出现奇数次,奇数出现偶数次。

    用三进制表示0~9的状态

    //============================================================================
    // Name        : SPOJ.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    long long dp[20][60000];
    //3进制表示数字0~9的出现情况,0表示没有出现,1表示奇数次,2表示偶数次
    int bit[20];
    bool check(int s)
    {
        int num[10];
        for(int i=0;i<10;i++)
        {
            num[i]=s%3;
            s/=3;
        }
        for(int i=0;i<10;i++)
            if(num[i]!=0)
            {
                if(i%2==0 && num[i]==2)return false;
                if(i%2==1 && num[i]==1)return false;
            }
        return true;
    }
    int getnews(int x,int s)
    {
        int num[10];
        for(int i=0;i<10;i++)
        {
            num[i]=s%3;
            s/=3;
        }
        if(num[x]==0)num[x]=1;
        else num[x]=3-num[x];
        int news=0;
        for(int i=9;i>=0;i--)
        {
            news*=3;
            news+=num[i];
        }
        return news;
    }
    long long dfs(int pos,int s,bool flag,bool z)
    {
        if(pos==-1)return check(s);
        if(!flag && dp[pos][s]!=-1)
            return dp[pos][s];
        long long ans=0;
        int end=flag?bit[pos]:9;
        for(int i=0;i<=end;i++)
            ans+=dfs(pos-1,(z&&i==0)?0:getnews(i,s),flag&&i==end,z&&i==0);
        if(!flag)dp[pos][s]=ans;
        return ans;
    }
    long long calc(long long n)
    {
        int len=0;
        while(n)
        {
            bit[len++]=n%10;
            n/=10;
        }
        return dfs(len-1,0,1,1);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T;
        memset(dp,-1,sizeof(dp));
        long long a,b;
        scanf("%d",&T);
        while(T--)
        {
            cin>>a>>b;
            cout<<calc(b)-calc(a-1)<<endl;
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    微软一站式示例代码浏览器 v5.1 更新
    Developers’ Musthave: the new Microsoft AllInOne Code Framework Sample Browser and 3500+ samples
    栈溢出攻击 [转]
    深入浅出Java的访问者模式 [转]
    优先级反转 [转]
    latex 引用section [转]
    linux内存管理浅析 [转]
    静态,动态,强类型,弱类型 [转]
    linux硬链接与软链接 [转]
    GCC __attribute__ 详解 [转]
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3052883.html
Copyright © 2020-2023  润新知