• HDU-3709 Balanced Number 数位dp+枚举


    一个数字是平衡数字,当且仅当存在它的一个数位作为平衡点,这个点左边和右边【数字*到这个点的距离】之和相等

    容易知道一个平衡数字只有一个平衡位置

    设状态为dp[pos][n][sum]表示当前第pos位,平衡点在n,当前的距离为sum,枚举平衡位置

    距离不取绝对值,这样sum最终为0就是可行解,而且sum小于0就可以剪枝加快速度

    那么枚举时计算sum就是先正后负也就是pos-n而非n-pos,从高位往低位枚举每次sum+(pos-n)*i在n点前一定是正数

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define LL long long
     5 using namespace std;
     6 
     7 int a[20];
     8 LL dp[20][20][3000];
     9 
    10 LL dfs(int pos, int sum, int len, bool lim){
    11     if (pos == -1) return sum == 0;
    12     if (sum < 0) return 0;
    13     if (!lim && dp[pos][len][sum] != -1) return dp[pos][len][sum];
    14     LL ans = 0;
    15     int r = lim ? a[pos] : 9;
    16     for (int i = 0; i <= r; i++)
    17         ans += dfs(pos-1, sum+(pos-len)*i, len, lim && i == a[pos]);
    18     if (!lim) dp[pos][len][sum] = ans;
    19     return ans;
    20 }
    21 
    22 LL solve(LL x){
    23     int pos = 0;
    24     while (x){
    25         a[pos++] = x%10;
    26         x /= 10;
    27     }
    28     LL ans = 0;
    29     for (int i = 0; i < pos; i++)
    30         ans += dfs(pos-1, 0, i, 1);
    31     return ans - pos + 1;
    32 }
    33 
    34 int main(){
    35     int t;
    36     LL l, r;
    37     scanf("%d", &t);
    38     memset(dp, -1, sizeof dp);
    39     while (t--){
    40         scanf("%lld%lld", &l, &r);
    41         printf("%lld
    ", solve(r)-solve(l-1));
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    2019年8月20日 item系列
    变量和字符
    python命名规则
    五大常用算法之贪心算法
    过河卒
    组成三位数
    编码问题
    FatMouse' Trade
    A Boring Game
    螺旋矩阵
  • 原文地址:https://www.cnblogs.com/QAQorz/p/9359558.html
Copyright © 2020-2023  润新知