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

    http://acm.hdu.edu.cn/showproblem.php?pid=3709

    数位dp,练模板好题。。

    题目要求求出[x, y] 范围内的平衡数,

    平衡数定义为:以数中某个位为轴心,两边的数的偏移量为矩,数位权重,使得整个数平衡。

    当然,首先可以简化一下条件~,设Kp以p为支点平衡度;

    Kp = sum(di*(i-p));  故△Kp = K(p+1) - Kp = -sum(di);

    记 ps = K0  (以0为支点平衡度), s = sum(di);

    所以条件存在Kp == 0等价为  s|ps.

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <stdlib.h>
     7 #define LL long long
     8 using namespace std;
     9 
    10 LL dp[20][1500][200];
    11 int d[20];
    12 
    13 LL dfs(int p, int ps, int s, bool e){    
    14         //ps: sum(di*i), s:sum(di) 
    15     if(p == -1)    return (s==0 || ps%s==0);    //s|ps; 
    16     if(!e && dp[p][ps][s]!=-1)    return dp[p][ps][s];
    17     int u=e? d[p]: 9;
    18     LL ans=0;
    19     for(int i=0; i<=u; i++)
    20         ans += dfs(p-1, ps+(s+i), s+i, e&&(i==u));
    21     return e? ans: (dp[p][ps][s] = ans);
    22 }
    23 
    24 LL f(LL x){
    25     int p=0;
    26     while(x){
    27         d[p++] = x%10;
    28         x /= 10;
    29     }
    30     return dfs(p-1, 0, 0, 1);
    31 }
    32 
    33 int main()
    34 {
    35     int T;
    36     cin >> T;
    37     LL m, n;
    38     memset(dp, -1, sizeof(dp));
    39     while(T--){
    40         cin >> m >> n;        
    41         cout << f(n)-f(m-1) << endl;
    42     }
    43     
    44     return 0;
    45 }
    46     
    View Code

    当然也可以直接做,枚举所有支点p,以及相应平衡度Kp ~

    记ps表示平衡度Kp,   s表示支点p。

    条件是  Kp == 0  。

    hint:  支点p不同时,Kp一定不同,除非△Kp ==0;

         故只有x == 0 时, 按支点划分,会重复。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <stdlib.h>
     7 #define LL long long
     8 using namespace std;
     9 
    10 LL dp[20][1500][20];
    11 int d[20];
    12 
    13 LL dfs(int p, int ps, int s, bool e){    
    14     if(p == -1)    return (ps==0);
    15     if(ps < 0)    return 0;     //平衡度<0, 必不满足, 剪枝。 
    16     if(!e && dp[p][ps][s]!=-1)    return dp[p][ps][s];
    17     int u=e? d[p]: 9;
    18     LL ans=0;
    19     for(int i=0; i<=u; i++)
    20         ans += dfs(p-1, ps+i*(p-s), s, e&&(i==u));
    21     return e? ans: (dp[p][ps][s] = ans);
    22 }
    23 
    24 LL f(LL x){
    25     int p=0;
    26     while(x){
    27         d[p++] = x%10;
    28         x /= 10;
    29     }
    30     LL ans = 0;
    31     for(int i=0; i<p; i++)    //按支点划分 
    32         ans += dfs(p-1, 0, i, 1);
    33     return ans-p+1;        //除去重复的0000000(p个0)的情况!! 
    34 }
    35 
    36 int main()
    37 {
    38     int T;
    39     cin >> T;
    40     LL m, n;
    41     memset(dp, -1, sizeof(dp));
    42     while(T--){
    43         cin >> m >> n;        
    44         cout << f(n)-f(m-1) << endl;
    45     }
    46     
    47     return 0;
    48 }
    View Code
  • 相关阅读:
    面试题19:包含min函数的栈
    编程之美 计算字符串的相似度
    android 数据持久化——I/O操作
    SSD磁盘,CPU居高不下,高并发的情况下,是不是mysql解析器耗费的cpu资源高?
    Eclipse、MyEclipse优化,提高运行速度
    Sonar入门学习
    Oracle 生成指定范围内随机日期
    ios中的GCD
    如何使用Win8系统自带杀毒软件
    安装Ubuntu版本linux过程中没有提示设置root用户密码问题的解决办法
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3426828.html
Copyright © 2011-2022 走看看