现在的位置: 首页 > 综合 > 正文

hdu3709 Balanced Number 数位dp

2019年09月03日 ⁄ 综合 ⁄ 共 1560字 ⁄ 字号 评论关闭

题意:定义一个数为“balanced number” 当其满足存在一个数位pos(平衡点),在pos左边的数位的值乘与pos位的距离值的总和等于右

的数位的值乘与pos位的距离值的总和,给定一个区间[l , r],求区间内有多少个balanced number。

思路:设dp[ pos ][ i ][ j ]表示平衡点在i位的情况下,当前考虑pos位,之前已形成的力矩为j(数乘以距离平衡点的距离,在平衡点左

边的为正,右边的为负),之后(pos + 1)位于之前位组合使最后平衡(力矩为0)的数的个数,详见代码:

/*********************************************************
  file name: hdu3709.cpp
  author : kereo
  create time:  2015年01月24日 星期六 15时27分47秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=20;
const int MAXN=1500+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int bit[N]; 
ll dp[N][N][MAXN]; //dp[pos][i][j]表示在平衡点为i的情况下,当前考虑pos位,之前已形成的力矩为j,之后(pos+1)位与之前位组合使最后平衡的个数
ll dfs(int pos,int o,int st,int flag){
    if(pos == -1) return st == 0;
    if(flag && dp[pos][o][st]!=-1)
        return dp[pos][o][st];
    int x=flag ? 9 : bit[pos];
    ll ans=0;
    for(int i=0;i<=x;i++){
        int nst=st+(pos-o)*i;
        if(nst<0) //力矩为负直接continue
            continue;
        ans+=dfs(pos-1,o,nst,flag || i<x);
    }
    if(flag)
        dp[pos][o][st]=ans;
    return ans;
}
ll solve(ll x){
    int len=0;
    if(!x)
        bit[len++]=x;
    while(x){
        bit[len++]=x%10;
        x/=10;
    }
    ll ans=0;
    for(int i=0;i<len;i++)
        ans+=dfs(len-1,i,0,0);
    ans-=len-1; //考虑零的重复计算
    return ans;
}
int main(){
    memset(dp,-1,sizeof(dp));
    int T;
    scanf("%d",&T);
    while(T--){
        ll n,m;
        scanf("%I64d%I64d",&n,&m);
        ll ans1= n == 0 ? 0: solve(n-1);
        ll ans2=solve(m);
        printf("%I64d\n",ans2-ans1);
    }
	return 0;
}

抱歉!评论已关闭.