zoj 3416 Balanced Number 数位dp

来源:互联网 发布:淘宝信誉多少一个皇冠 编辑:程序博客网 时间:2024/06/16 13:53

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

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

<h4< dd="">
Output

For each case, print the number of balanced numbers in the range [xy] in a line.

<h4< dd="">
Sample Input
20 97604 24324
<h4< dd="">
Sample Output
10897
题意:让我们找l~r之间的平衡数的个数,平衡数的定义是存在一位作为对称轴,使得两边的 数*权值之和相等,例如题意中给出的例子,4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9,
思路:数位dp,还是枚举对称轴后数位dp就可以了,dp[i][j][k],i表示i位,j表示对称轴前边的量-后边的量  k表示对称轴
ac代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int num[20];long long dp[20][3600][20];long long dfs(int len,int sum,int tmp,int f){    if(len<0)    return sum==0;    if(sum<0)    return 0;    if(!f&&dp[len][sum][tmp]!=-1)    return dp[len][sum][tmp];    int fp=f?num[len]:9;    long long ret=0;    for(int i=0;i<=fp;i++)    {        ret+=dfs(len-1,sum+(len-tmp)*i,tmp,f&&i==fp);    }    if(!f)    dp[len][sum][tmp]=ret;    return ret;}long long get_num(long long x){    int len=0;    while(x)    {        num[len++]=x%10;        x=x/10;    }    long long ans=0;    for(int i=0;i<len;i++)    ans+=dfs(len-1,0,i,1);    return ans-(len-1);}int main(){    int t;    cin>>t;    memset(dp,-1,sizeof(dp));    while(t--)    {        long long a,b;        cin>>a>>b;        cout<<get_num(b)-get_num(a-1)<<endl;    }    return 0;}


原创粉丝点击