zoukankan      html  css  js  c++  java
  • [hdu3709]Balanced Number(数位dp)

    题意:在l-r之间寻找可以满足平衡数条件的个数。

    解题关键:数位dp,由于非零数的支点有且只存在一个,故只有0存在重复,最后需要删去。

    1001也只存在1种情况的,仔细想想。

    转移方程:$dp[i][j] +  = dp[i - 1][j - a[i]*(o - i)]$

    法一:390ms

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll dp[20][2000],l,r;
    int t[20],o;
    ll dfs(int pos,int sta,int limit){
        if(pos==-1) return sta==0;
        if(sta<0) return 0;
        if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
        ll up=limit?t[pos]:9,ans=0;
        for(int i=0;i<=up;i++)
            ans+=dfs(pos-1,sta+(pos-o)*i,limit&&i==up);
        if(!limit) dp[pos][sta]=ans;
        return ans;
    }
    ll solve(ll x){
        int pos=0;
        while(x){
            t[pos++]=x%10;
            x/=10;
        }
        ll ans=0;
        for(int i=0;i<pos;i++) memset(dp,-1,sizeof dp),o=i,ans+=dfs(pos-1,0,1);
        return ans-pos+1;
    }
    int main(){
        int T;scanf("%d",&T);
        memset(dp,-1,sizeof dp);
        while(T--){
            scanf("%lld%lld",&l,&r);
            printf("%lld
    ",solve(r)-solve(l-1));
        }
        return 0;
    }

    法二:将支点位置hash一下,31ms

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll dp[20][20][2000],l,r;
    int t[20],o;
    ll dfs(int pos,int sta,int limit){
        if(pos==-1) return sta==0;
        if(sta<0) return 0;
        if(!limit&&dp[pos][o][sta]!=-1) return dp[pos][o][sta];
        ll up=limit?t[pos]:9,ans=0;
        for(int i=0;i<=up;i++)
            ans+=dfs(pos-1,sta+(pos-o)*i,limit&&i==up);
        if(!limit) dp[pos][o][sta]=ans;
        return ans;
    }
    ll solve(ll x){
        int pos=0;
        while(x){
            t[pos++]=x%10;
            x/=10;
        }
        ll ans=0;
        for(int i=0;i<pos;i++) o=i,ans+=dfs(pos-1,0,1);
        return ans-pos+1;
    }
    int main(){
        int T;scanf("%d",&T);
        memset(dp,-1,sizeof dp);
        while(T--){
            scanf("%lld%lld",&l,&r);
            printf("%lld
    ",solve(r)-solve(l-1));
        }
        return 0;
    }
  • 相关阅读:
    python 全局变量与局部变量
    Python 百分号字符串拼接
    Python集合的基本操作
    sorted by value in dict python
    gVim vundle
    vim config
    vim move the cursor in a long sentence
    步步为营-37-自动生成数据库连接字符串
    步步为营-36-ADO.Net简介
    步步为营-35-SQL语言基础
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7790245.html
Copyright © 2011-2022 走看看