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; } /******************** ********************/