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
  • 相关阅读:
    Problem E. Matrix from Arrays(杭电2018年多校第四场+思维+打表找循环节)
    Reachability from the Capital(Codeforces Round #490 (Div. 3)+tarjan有向图缩点)
    Network of Schools(POJ1326+有向图进行缩点)
    John's trip(POJ1041+欧拉回路+打印路径)
    Watchcow(POJ2230+双向欧拉回路+打印路径)
    Network(POJ3694+边双连通分量+LCA)
    Problem L. Visual Cube(杭电多校2018年第三场+模拟)
    floyd骚操作——传递闭包
    Remmarguts' Date(POJ2449+最短路+A*算法)
    Transformation(线段树+HDU4578+多种操作+鬼畜的代码)
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3426828.html
Copyright © 2011-2022 走看看