zoukankan      html  css  js  c++  java
  • 【HDU 3709】 Balanced Number (数位DP)

    Balanced Number



    Problem Description
    A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9, for left part and right part, respectively. It's your job
    to calculate the number of balanced numbers in a given range [x, y].
    Input
    The input contains multiple test cases. The first line is the total number of cases T (0 < T ≤ 30). For each case, there are two integers separated by a space in a line, x and y. (0 ≤ x ≤ y ≤ 1018).
    Output
    For each case, print the number of balanced numbers in the range [x, y] in a line.
    Sample Input
    2 0 9 7604 24324
    Sample Output
    10 897
    Author
    GAO, Yuan
    Source
     
     
    【题意】
     
        一个数n是平衡数当且仅当选一个位置j时,对于每一位(i-j)*a[i]的和为0,例如4139,4921,求l到r中有多少个平衡数(l<=r<=2^63-1)多组数据
     
    【分析】
     
      

      一开始纠结的地方呢就是一个数可不可能有两个平衡点。。然后就觉得会重复。
      用物理的思想想的话好像一个物体又没有两个重心??可是我不会用数学方法严谨证明ORZ。。。
      然后就是普通的数位DP,f[i][j][k]表示填i位j是平衡点,然后k是当前的计算值。(不超过4000)
      记忆化搜索大法好,又快又好打,特别是多组!!

      记得减掉00、000、0000的!

    代码如下:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define LL long long
    10 
    11 LL f[20][20][4010];
    12 int a[20],c;
    13 
    14 LL ffind(int n,int k,int sum,bool flag)
    15 {
    16     if(n==0) return (sum==0);
    17     if(!flag&&f[n][k][sum]!=-1) return f[n][k][sum];
    18     int ed=flag?a[n]:9;
    19     LL ans=0;
    20     for(int i=0;i<=ed;i++)
    21       ans+=ffind(n-1,k,sum+i*(k-n),flag&&(i==ed));
    22     if(!flag) f[n][k][sum]=ans;
    23     return ans;
    24 }
    25 
    26 LL get_ans(LL n)
    27 {
    28     if(n==-1) return 0;
    29     if(n==0) return 1;
    30     c=0;
    31     LL x=n;
    32     while(x) a[++c]=x%10,x/=10;
    33     LL ans=0;
    34     for(int i=1;i<=c;i++) ans+=ffind(c,i,0,1);
    35     return ans-c+1;
    36 }
    37 
    38 int main()
    39 {
    40     int T;
    41     scanf("%d",&T);
    42     memset(f,-1,sizeof(f));
    43     while(T--)
    44     {
    45         LL x,y;
    46         scanf("%lld%lld",&x,&y);
    47         get_ans(0);
    48         LL ans=get_ans(y)-get_ans(x-1);
    49         printf("%lld
    ",ans);
    50     }
    51     return 0;
    52 }
    [HDU 3709]

    感觉我没有判负就A了?!!

    2016-10-08 20:31:48

  • 相关阅读:
    KVC该机制
    JS多语种方式
    面试经典(1)---翻转字的顺序在一个句子
    正确Linux新手很实用20命令
    代码添加背景音乐的日记
    什么是比特币(Bitcoin)?
    李开复:该算法的重要性
    javascript推断的浏览器类型
    libyuv编
    Linux下将UTF8编码批量转换成GB2312编码的方法
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5940021.html
Copyright © 2011-2022 走看看