HDU-3709-Balanced Number(数位DP+记忆化DFS)

来源:互联网 发布:软件体系结构评估报告 编辑:程序博客网 时间:2024/05/18 12:36

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709

题意:求[a,b]区间内Balanced Number的个数,Balanced Number:当前数以某点p为支点满足sigma a[i]*(i-p) =0,(即物理杠杆平衡)

题解:数位DP,dp[pos][ful][sum],///dp[当前位][支点][合力],枚举支点,记忆化搜索并记录已有值,另外有限制的时候是不可纪录的,最后答案减去0的时候len-1个支点的个数

CODE:


#include <bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fconst int maxn = 1e5+7;int a[21];long long dp[21][21][3010];///dp[pos][ful][sum];///dp[当前位][支点][合力];long long dfs(int pos, int ful, int temp, int flag){    if(temp<0)return 0;    if(pos<1)return temp==0;    if(!flag&&dp[pos][ful][temp]!=-1)return dp[pos][ful][temp];    long long ans=0;    int M=flag?a[pos]:9;    for(int i=0; i<=M; ++i)    {        int p=(pos-ful)*i;        if(i==M)ans+=dfs(pos-1,ful,temp+p,flag);        else ans+=dfs(pos-1,ful,temp+p,0);    }    if(!flag)dp[pos][ful][temp]=ans;    return ans;}long long solve(long long x){    if(x<0)return 0;    int len=0;    long long temp=x;    while(x)    {        a[++len]=x%10;        x/=10;    }    long long ans=0;    for(int i=len; i>0; --i)    {        ans+=dfs(len,i,0,1);    }    return ans-len+1;}int main(){    int T;    long long x,y;    memset(dp,-1,sizeof(dp));    scanf("%d",&T);    while(T--)    {        scanf("%I64d%I64d",&x,&y);        cout<<solve(y)-solve(x-1)<<endl;;    }    return 0;}/*20 97604 24324*/









0 0