zoukankan      html  css  js  c++  java
  • HDU 3709 Balanced Number

    Balanced Number

    题意: 平衡数:存在该数中以一个数字为支点(pivot),点的"力矩"为该点到支点的距离乘以该点的值,而平衡指的是支点两侧的力矩和相等

    思路:

      易知当支点相同时,只要前面的力矩相等,那么就可以建立相同的子结构。那么dp中就要把支点加进去,同时力矩也要加进去,外加位置就是三维。原本分析认为位置可以不加,但是发现少计算了很多。同时看static里面,memory用得最小的也是将近小了20倍,觉得这一维也是可以去掉的。以后想到在贴出来吧!

      支点的转化:原本想直接在dfs里面看看能否设置为一个pivot动一个不动,但是没搞出来,之后就直接枚举了...每次数位DP都要看看前置0的影响。这道题每一个支点都会有一个0,所以减去重复的即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define MS1(a) memset(a,-1,sizeof(a))
    #define MS0(a) memset(a,0,sizeof(a))
    typedef long long ll;
    int bit[23];
    ll dp[20][1800][20];
    ll dfs(int pos,int val,int pivot,bool edge)
    {
        if(val < 0) return 0;
        if(pos == -1) return val == 0;
        if(!edge && dp[pos][val][pivot] >= 0) return dp[pos][val][pivot];
        int end = edge ? bit[pos] : 9;
        ll ans = 0;
        for(int i = 0;i <= end;i++){
            ans += dfs(pos - 1,val+i*(pos - pivot),pivot,edge&&(i==end));
        }
        if(!edge) dp[pos][val][pivot] = ans;
        return ans;
    }
    ll calc(ll n)
    {
        if(n == -1) return 0;
        int tot = 0;
        while(n){
            bit[tot++] = n%10;
            n /= 10;
        }
        ll ans = 0;
        for(int i = tot - 1;i >= 0;i--)
            ans += dfs(tot - 1,0,i,true);
        return ans - tot + 1;
    }
    int main()
    {
        MS1(dp);
        int T;
        scanf("%d",&T);
        while(T--){
            ll L,R;
            scanf("%I64d%I64d",&L,&R);
            printf("%I64d
    ",calc(R) - calc(L-1));
        }
    }
    View Code
  • 相关阅读:
    Centos服务器搭建(3)——安装maven
    Centos服务器搭建(2)——安装tomcat
    Centos服务器搭建(1)——安装jdk
    mysql主从复制
    Json中返回换行符处理
    github pages 绑定域名
    SharePoint学习笔记——子页面
    SharePoint学习笔记——母版页
    SSH+Oracle的整合(SSH与Oracle整合坑巨多)
    SSH整合做CRUD(大神老师整理)
  • 原文地址:https://www.cnblogs.com/hxer/p/5177455.html
Copyright © 2011-2022 走看看