#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;} int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[2][2]={1,0 ,0,1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; int bits[20]; ll dp[20][20][2000]; //位数 平衡点位置 左右两边的和的差 ll dfs(int len,int pos,int sum,bool ismax){ if(!len) return sum==0; //如果左右相加为0就是平衡数 if(sum<0) return 0; //剪枝 if(!ismax&&dp[len][pos][sum]>=0) return dp[len][pos][sum]; int up=ismax?bits[len]:9; ll cnt=0; for(int i=0;i<=up;i++){ cnt+=dfs(len-1,pos,sum+(len-pos)*i,ismax&&i==up); } if(!ismax) dp[len][pos][sum]=cnt; return cnt; } ll solve(ll x){ int len=0; while(x){ bits[++len]=x%10; x/=10; } ll ans=0; for(int i=1;i<=len;i++){ //枚举分割点 ans+=dfs(len,i,0,true); } return ans-len-1; } int main(){ ios::sync_with_stdio(false); int t; cin>>t; memset(dp,-1,sizeof(dp)); while(t--){ ll x,y; cin>>x>>y; cout<<solve(y)-solve(x-1)<<endl; } return 0; }
hdu 3709 Balanced Number(数位dp)
原文:https://www.cnblogs.com/wmj6/p/10816686.html