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 }
View Code

 

 

 

posted @ 2013-09-06 09:30  _随心所欲_  阅读(202)  评论(0编辑  收藏  举报