码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3709 Balanced Number

时间:2016-02-02 16:12:34      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

Balanced Number

  • 题意: 平衡数:存在该数中以一个数为支点(pivot),点的"力矩"为该点到支点的距离乘以该点的值,而平衡指的是支点两侧的力矩和相等
  • 思路:
  1. 易知当支点相同时,只要前面的力矩相等,那么就可以建立相同的子结构。那么dp中就要把支点加进去,同时力矩也要加进去,外加位置就是三维。原本分析认为位置可以不加,但是发现少计算了很多。同时看static里面,memory用得最小的也是将近小了20倍,觉得这一维也是可以去掉的。以后想到在贴出来吧!

  2.支点的转化:原本想直接在dfs里面看看能否设置为一个pivot动一个不动,但是没搞出来,之后就直接枚举了...每次数位DP多要看看前置0的影响。这道题每一个支点都会有一个0,所以减去重复的即可。

 

技术分享
#include<bits/stdc++.h>
using namespace std;
#define MS1(a) memset(a,-1,sizeof(a))
#define MS0(a) memset(a,0,sizeof(a))
typedef long long ll;
int bit[23];
ll dp[20][1800][20];
ll dfs(int pos,int val,int pivot,bool edge)
{
    if(val < 0) return 0;
    if(pos == -1) return val == 0;
    if(!edge && dp[pos][val][pivot] >= 0) return dp[pos][val][pivot];
    int end = edge ? bit[pos] : 9;
    ll ans = 0;
    for(int i = 0;i <= end;i++){
        ans += dfs(pos - 1,val+i*(pos - pivot),pivot,edge&&(i==end));
    }
    if(!edge) dp[pos][val][pivot] = ans;
    return ans;
}
ll calc(ll n)
{
    if(n == -1) return 0;
    int tot = 0;
    while(n){
        bit[tot++] = n%10;
        n /= 10;
    }
    ll ans = 0;
    for(int i = tot - 1;i >= 0;i--)
        ans += dfs(tot - 1,0,i,true);
    return ans - tot + 1;
}
int main()
{
    MS1(dp);
    int T;
    scanf("%d",&T);
    while(T--){
        ll L,R;
        scanf("%I64d%I64d",&L,&R);
        printf("%I64d\n",calc(R) - calc(L-1));
    }
}
View Code

 

HDU 3709 Balanced Number

标签:

原文地址:http://www.cnblogs.com/hxer/p/5177455.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!