数位DP--ZOJ3416(Balanced Number)

来源:互联网 发布:江苏运时数据电话 编辑:程序博客网 时间:2024/06/13 22:52
ZOJ Problem Set - 3416
Balanced Number

Time Limit: 5 Seconds      Memory Limit: 65536 KB

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 casesT (0 < T ≤ 30). For each case, there are two integers separated by a space in a line,x and y. (0 ≤ xy ≤ 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

 

 

数位DP状态转移感觉比普通DP好想些,因为很容易从上一阶段推出下一阶段的状态,有一定的规律性,而且记忆化写出来的代码非常美观易懂,nice~~

/*********************************************************************** problem:Balanced Number* source:The 2010 ACM-ICPC Asia Chengdu Regional Contest* author:crazy_石头* 题意分析:对于一个数,如4139,以3为枢轴,有4*2+1*1==9*1称这样的数为* Balanced Number,此时支点centre是唯一的,所以不会有重复计数的情况* (但有一种特殊的,就是0,00,000等都是一样的,会计算多次,* 最后减去即可)* 假设检查到pos处,对于上面的式子sigma(a[i]*(i-centre))=0,这里确定了支点为centre* 之前的数其sigma(a[i]*(i-centre))的结果为pre* 所以参数需要为pos,centre,pre* 当检查到pos=-1时,return pre == 0* 否则,看当前是计算所有情况还是具体情况(limit)* 即根据limit的值选择下一个位置处理的数;* 如果是所有情况且dp值!=-1,直接return* 否则就枚举0到end* 而支点o需要在最外层枚举出来***********************************************************************/#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#define A system("pause")using namespace std;typedef long long LL;const int maxn=20;const int maxm=2000;LL dp[maxn][maxn][maxm];LL digit[maxn];inline void debug(){     printf("where is wrong?\n");}inline LL DFS(int pos,int centre,int pre,bool limit){    if(pos==-1)        return pre==0;    if(!limit&&dp[pos][centre][pre]!=-1)        return dp[pos][centre][pre];    //debug();     LL ans=0;     int end=limit?digit[pos]:9;     for(int i=0;i<=end;i++)     {        int new_pre=pre;         new_pre+=(pos-centre)*i;;         ans+=DFS(pos-1,centre,new_pre,limit&&i==end);     }     if(!limit)         dp[pos][centre][pre]=ans;     return ans;}inline LL solve(LL n){     int len=0;     while(n)     {         digit[len++]=n%10;         n/=10;     }     LL res=0;     for(int i=0;i<len;i++)     {         res+=DFS(len-1,i,0,1);     }     return res-(len-1);}int main(){     int test;     LL m,n;     scanf("%d",&test);     memset(dp,-1,sizeof(dp));     while(test--)     {         scanf("%lld%lld",&m,&n);         printf("%lld\n",solve(n)-solve(m-1));     }     return 0;}/**********************************************************   友情附带大牛blog:*   kuangbin(bin神):  http://www.cnblogs.com/kuangbin/*   wuyiqi神:         http://blog.csdn.net/crazy_ac*   ORZ爱神:          http://blog.csdn.net/acm_cxlove*   木子日匀(李昀神牛):http://www.mzry1992.com/blog/*********************************************************/


 

原创粉丝点击