hdu 3709 数位dp

数位dp,有了进一步的了解,模板也可以优化一下了

题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数
例如4139,以3为支点
4*2 + 1*1 = 9 and 9*1 = 9,称为平衡数

Sample Input
2
0 9
7604 24324

Sample Output
10
897

 

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 __int64 dp[19][19][2000];
 5 int digit[19];
 6 __int64 dfs(int p,int o,int s,bool e) {       //数位,支点位置,前面到支点的和,是否任意填
 7     if (p==-1) return s==0;
 8     if(s<0)    return 0;
 9     if (!e &&dp[p][o][s]!=-1) return dp[p][o][s];
10     __int64 res = 0;
11     int u = e?digit[p]:9;
12     for (int d=0;d<=u;++d)
13     {
14         int ns=d*(p-o)+s;
15         res+=dfs(p-1,o,ns,e&&d==u);
16     }
17     return e?res:dp[p][o][s]=res;
18 }
19 __int64 solve(__int64 n)
20 {
21     int len=0;
22     while(n)
23     {
24         digit[len++]=n%10;
25         n/=10;
26     }
27     __int64 ans=0;
28     for(int i=0;i<len;i++)
29     {
30         ans+=dfs(len-1,i,0,1);
31     }
32     return ans-len+1;
33 }
34 int main()
35 {
36     int t;
37     __int64 n,m;
38     //freopen("1.in","r",stdin);
39     memset(dp,-1,sizeof(dp));
40     scanf("%d",&t);
41     while(t--)
42     {
43         scanf("%I64d%I64d",&n,&m);
44         printf("%I64d\n",solve(m)-solve(n-1));
45     }
46 }

 

posted @ 2015-01-30 15:44  miao_a_miao  阅读(141)  评论(0编辑  收藏  举报