zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Python学习笔记之递归函数
    包管理工具-yum
    ElasticSearch定时清理缓存索引
    pytest实现多进程与多线程运行
    获取webView页面内窗体句柄
    文档测试
    ClickHouse 运维相关部分命令记录
    [转]contains a file system with errors, check forced
    log日志重复打印 修改
    jmeter参数化
  • 原文地址:https://www.cnblogs.com/QAQorz/p/9359558.html
Copyright © 2011-2022 走看看