zoj3416 Balanced Number

链接

这题纠结了好久,刚开始想到的是正解,不过想到可能会出现一个数支点不唯一的情况,这样就多算了,其实是我想多了,一个数只有一个支点。

这样就好像想到了,枚举支点的位置,保存力矩的状态。

dp[i][k][s] i为当前处理位 k为支点 s为到目前为止根据支点算出来的部分力矩。

有一点需要注意算0的时候 会有len个支点 所以要减掉重算的len-1个

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 2550
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 LL dp[20][20][N];
18 int d[20],g;
19 LL dfs(int i,bool e,int k,int s)
20 {
21     if(s<0) return 0;
22     if(i==-1)
23     return s==0;
24     if(!e&&~dp[i][k][s])
25     return dp[i][k][s];
26     int mk = e?d[i]:9;
27     LL ans = 0 ;
28     for(int j = 0 ;j <= mk ;j++)
29     {
30         //ans+=dfs(i-1,e&&j==mk,s+=j*i,sum+=j);
31         ans+=dfs(i-1,e&&j==mk,k,s+(i-k)*j);
32     }
33    // cout<<ans<<" "<<i<<endl;
34     return e?ans:dp[i][k][s] = ans;
35 }
36 LL cal(LL x)
37 {
38     if(x<0) return 0;
39     if(x==0) return 1;
40     g = 0;
41     while(x)
42     {
43         d[g++] = x%10;
44         x/=10;
45     }
46     LL ans = 0;
47     for(int i = 0;i < g ; i++)
48     {
49         ans+=dfs(g-1,1,i,0);
50     }
51     //return dfs(g-1,1,N,0);
52     return ans-g+1;
53 }
54 int main()
55 {
56     int t;
57     LL l,r;
58     cin>>t;
59     memset(dp,-1,sizeof(dp));
60     while(t--)
61     {
62         cin>>l>>r;
63         cout<<cal(r)-cal(l-1)<<endl;
64     }
65     return 0;
66 }
View Code

 

posted @ 2014-04-23 20:59  _雨  阅读(172)  评论(0编辑  收藏  举报