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

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


憋了一中午才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;
}


全部评论

相关推荐

昨天 16:33
门头沟学院 Java
本人某中9本科,成绩中等,目前没科研没实习,目前后端学到了javaWeb,开始没定好方向,在学国外课程,走工程路线起步有点晚了,到这个时间点了还在学JavaWeb,顿感迷茫,不知道是坚持走下去还是寒假去准备考研。考研这个路弄得我还是心痒痒的,因为从众考研的人也不在少数,所以会有这方面的心理安慰吧,就是“不行我可以去考研啊”,而且意味着三年的缓冲,为了复试还有积攒经验美化简历,其实现在也可以去申入实验室打杂;就业可能意味着多些工作经验,工程岗应该到后面还是经验大于学历?还是有点迷茫了,求助好心人有无路线启发
千千倩倩:同27给点建议,现在这个时间点可以快速看完外卖和点评,不用跟着敲,但一定要在看的时候总结每个部分的整个业务流程,对其中的实现有一个大概的印象。然后直接开始看八股,刷算法。八股和算法最好还是在项目学习中穿插着看。如果计算机基础,算法这些基础好,加上每天刻苦学习,两周可以达到勉强能面试的水平,到时候就直接海投中小厂,在约面和面试的过程中不断巩固知识。没找到实习也没关系,就当积累经验。再沉淀一波直接明年三月开始投暑期,毕竟是9本,总是有面试机会的,只要你这三个月不懈怠,面试发挥得一定不错,只要拿到一个中,大厂暑期实习,秋招就有竞争力了。总得而言,现在还有机会,但是时间非常紧张,需要你结合自己情况考虑,共勉
你会选择考研还是直接就业
点赞 评论 收藏
分享
迷茫的大四🐶:摊牌了,我是25届的,你们也不招我
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务