hdu 3709 Balanced Number 数位DP
思路:
dp[i][j][k]:表示以j为支点时两边和为k的个数
注意去掉0,00,000……等。
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll __int64 5 using namespace std; 6 int bit[20]; 7 ll dp[20][20][2000]; 8 ll dfs(int pos,int pre,int o,bool f) 9 { 10 if(pos==-1) return pre==0; 11 if(!f&&dp[pos][o][pre]!=-1) return dp[pos][o][pre]; 12 ll ans=0; 13 int e=f?bit[pos]:9; 14 for(int i=0;i<=e;i++) 15 ans+=dfs(pos-1,pre+i*(pos-o),o,f&&(i==bit[pos])); 16 if(!f) dp[pos][o][pre]=ans; 17 return ans; 18 } 19 ll cal(ll n) 20 { 21 int m=0; 22 while(n){ 23 bit[m++]=n%10; 24 n/=10; 25 } 26 ll ans=0; 27 for(int o=0;o<m;o++) 28 ans+=dfs(m-1,0,o,1); 29 return ans-(m-1); 30 } 31 int main() 32 { 33 ll n,m; 34 int t; 35 memset(dp,-1,sizeof(dp)); 36 scanf("%d",&t); 37 while(t--){ 38 scanf("%I64d%I64d",&n,&m); 39 printf("%I64d\n",cal(m)-cal(n-1)); 40 } 41 }