hdu3709Balanced Number【数位dp】

F.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical Charts
Problem Archive
Realtime Judge Status
Authors Ranklist
 
      C/C++/Java Exams     
ACM Steps
Go to Job
Contest LiveCast
ICPC@China
Best Coder beta
VIP | STD Contests
Virtual Contests 
    DIY | Web-DIY beta
Recent Contests
Author 20130738
Mail Mail 0(0)
Control Panel Control Panel 
Sign Out Sign Out
招生——杭电“三位一体”全攻略! 
招聘——巴卡斯科技(杭州)、英雄互娱(杭州)

Balanced Number

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 3549    Accepted Submission(s): 1630


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

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
2010 Asia Chengdu Regional Contest


憋了一中午才A掉的题==也算是数位dp中比较经典的了

说题意:给定已知数字串,要求以某个数字为中心的两侧力矩和相等的个数,我们考虑三个与结果相关的量:当前枚举的到的长度、轴的位置、力矩和,分别作为dp的三维

flag用以标记最大位是否使用,注意sum<0退出;pos=0时候,如果sum=0那么方法数相当于+1,因要求是==0嘛,也就是说,在递归的过程中,pos center的相对位置不定,pos挪到右边依旧是pos-center那么就是加上负值了== 到最后flag=0时,我们可以认为当前情况遍历完毕,才可以为dp赋值

好好理解这个题才能做出来下一个poj3252呢--

/************
hdu3709
2016.3.11
31MS	22860K	1075 B	C++
************/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long dp[30][30][3000];
int num[30];
long long dfs(int pos,int center,int sum,bool flag)
{
    if(pos==0) return sum==0;
    if(sum<0) return 0;
    if(!flag&&dp[pos][center][sum]!=-1) return dp[pos][center][sum];
    long long ans=0;
    int maxn=flag?num[pos]:9;
    for(int i=0;i<=maxn;i++)
    {
        ans+=dfs(pos-1,center,sum+i*(pos-center),i==maxn&&flag);
    }//pos-center
    if(!flag) dp[pos][center][sum]=ans;
    return ans;
}
long long cal(long long x)
{
    long long ans=0;
    int pos=0;
    while(x)
    {
        num[++pos]=x%10;
        x/=10;
    }
    for(int i=1;i<=pos;i++)
    ans+=dfs(pos,i,0,1);
    return ans-pos+2;
}
int main()
{
    //freopen("cin.txt","r",stdin);
    int t;
    long long n,m;
    memset(dp,-1,sizeof(dp));
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&m);
        printf("%I64d\n",cal(m)-cal(n-1));
    }
    return 0;
}


你可能感兴趣的:(dp,杭电)