您的位置:首页 > 其它

HDU 3709 Balanced Number (数位DP)

2015-10-04 22:37 246 查看
题意:

  找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数。

思路:

  一开始以为需要枚举位数,枚举前缀和,枚举后缀和,一旦枚举起来就会MLE。

  其实只需要3维 [第几位][和][轴位置],对于轴的位置是需要枚举的,每个位都是有可能的,比如900和7都是一个平衡数。注意这道题的区间下限可能为0,而0也是平衡数,这在拆十进制的时候len=0的,最好将0特处理。

#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI  = acos(-1.0);
const int N=19;

LL f
[325]
, bit
;
//[第几位][和][轴]

LL dfs(int i,int sum,int mid,bool e)
{
if(i==0)    return sum==0;
if(sum<0 || sum>=325)    return 0;
if(!e && ~f[i][sum][mid])    return f[i][sum][mid];

LL ans=0;
int u= e? bit[i]: 9;
for(int d=0; d<=u; d++)
{
if(sum==0 && i==mid && d==0)    continue;    //首位是mid,必须不为0
ans+=dfs(i-1, sum+(i-mid)*d, mid, e&&d==u);    //注意不能为负
}
return e? ans: f[i][sum][mid]=ans;
}

LL cal(LL n)
{
if(n<0)        return 0;
int len=0;
while(n)    //拆数
{
bit[++len]=n%10;
n/=10;
}
LL ans=1;    //dfs是没有统计0的,因为len=0是不会执行dfs的
for(int i=1; i<=len; i++)
ans+=dfs(len, 0, i, true);
return ans;
}

int main()
{
//freopen("input.txt","r",stdin);
memset(f,-1,sizeof(f));
LL L,R;int t;cin>>t;
while( t-- )
{
cin>>L>>R;
cout<<cal(R)-cal(L-1)<<endl;
}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: