hdu3709 数位dp

题意:求某一区间内的平衡数(指在某一数位开始,左右两边的权值相同,如4119:4*2+1*1=9*1,以1 为支点,该数是平衡数)

题解:枚举所有的支点,求和,dp【i】【j】【k】i是位数,j是支点位置,k是两端权值和,左边为正,右边为负,i为0时,k为0,那么该数就是平衡数

#include<bits/stdc++.h>
#define C 0.5772156649
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const double g=10.0,eps=1e-7;
const int N=20+10,maxn=2000+10,inf=0x3f3f3f;

int digit[N];
ll dp[N][N][maxn];
ll dfs(int len,int point,int l,bool fp)
{
    if(!len)return l==0;
    if(l<0)return 0;
    if(!fp&&dp[len][point][l]!=-1)return dp[len][point][l];
    ll ans=0,fpmax=fp ? digit[len] : 9;
    for(int i=0;i<=fpmax;i++)
    {
        int Next=l;
        Next+=(len-point)*i;
        ans+=dfs(len-1,point,Next,fp&&i==fpmax);
    }
    if(!fp)dp[len][point][l]=ans;
    return ans;
}
ll solve(ll x)
{
    int len=0;
    while(x)
    {
        digit[++len]=x%10;
        x/=10;
    }
    ll ans=0;
    for(int i=1;i<=len;i++)
    {
        ans+=dfs(len,i,0,1);
    }
    return ans-len;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    memset(dp,-1,sizeof dp);
    while(t--)
    {
        ll l,r;
        cin>>l>>r;
        cout<<solve(r)-solve(l-1)<<endl;
    }
    return 0;
}
/********************

********************/
View Code

 

posted @ 2017-09-01 12:28  walfy  阅读(125)  评论(0编辑  收藏  举报