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 }