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;
    }
  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7790245.html
Copyright © 2011-2022 走看看