1. 程式人生 > >Balanced Number(數位DP)

Balanced Number(數位DP)

it is include 位數 integer 就是 text NPU \n space

D - Balanced Number

HDU - 3709

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].

InputThe 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 ≤ 10 18).OutputFor 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

題意:找出區間內平衡數的個數,所謂平衡數,就是以這個數字的某一位為支點,左右兩邊的數字乘力矩之和相等。
題解:比如4139
digit 4 1 3 9
len  4 3 2 1 對於每一位來說比如第四位4 for循環遍歷這一位的數字就是0~4 對於第三位1來說就是遍歷0~1。for循環遍歷每一位作為支點,然後對於dfs中從最高位到最低位搜一遍,對於4139這個數來說,假設支點在2位置,len從4~1,sum=4*2+1*1+3*0+9*(-1)=0 所以4139是一個平衡數,sum=0,返回1。遍歷完所有支點位置以及每一位從0到up,得到的和就是ans值。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 ll dp[20][20][2000];
 8 int digit[110];
 9 //dfs中4個參數,len代表當前所在的位數,zhou代表支點位置 
10 //sum代表支點左邊的數乘上力矩的加和-右邊的數乘上力矩的加和
11 //當sum為0時 代表以zhou這個位置為支點的存在一個數是平衡數。
12 //limit代表的是每一位的上限 
13 ll dfs(int len,int zhou,int sum,bool limit)
14 {
15     if(!len)
16         return sum?0:1;
17     if(!limit&&dp[len][zhou][sum]!=-1)
18         return dp[len][zhou][sum];
19     if(sum<0)
20         return 0;
21     int up=limit?digit[len]:9;
22     ll ans=0;
23     for(int i=0;i<=up;i++)
24     {
25         ans+=dfs(len-1,zhou,sum+i*(len-zhou),limit&&i==up);// sum+i*(len-zhou)表示當前的某一位上的某個數和它到支點距離的乘積 
26     }
27     if(!limit)
28         dp[len][zhou][sum]=ans;
29     return ans;
30 }
31 ll solve(ll x)
32 {
33     if(x<0)
34         return 0;
35     ll len=0;
36     while(x)
37     {
38         digit[++len]=x%10;
39         x/=10;
40     } 
41     ll ans=0;
42     for(int i=len;i>0;i--)
43     {
44         ans+=dfs(len,i,0,true);
45     }
46     return ans-len+1;//因為0 00 000只能算一個 
47 }
48 int main()
49 {
50     int casen;
51     cin>>casen;
52     memset(dp,-1,sizeof(dp));
53     while(casen--)
54     {
55         ll l,r;
56         scanf("%lld%lld",&l,&r);
57         printf("%lld\n",solve(r)-solve(l-1));    
58     } 
59     return 0;
60 } 

Balanced Number(數位DP)