题目链接:http://codeforces.com/problemset/problem/440/C
题目意思:给出一个数你,问需要用到的1来组成这个数的最少数量是多少。
我一开始对每个数只从 “+”的方向找,也就是假设对于4873,由千位开始配1,接着从百位,然后十位,最后个位。具体过程:4444 ---> 4888 ---> 4877 ---> 4873。对于test 3 的72我就悲剧了。因为最少数量应该是111 - 3*11 = 78, 78 - 5*1 = 72(15个1即可);而不是11*7 = 77, 77 - 5*11 = 72(19个1)(我的方法正是后者),得不到最少数量。
正确做法应该用搜索来做。唉~~~我对于dfs中递归总是很头痛,本来想利用人家的代码来调试(我只会用VC6调)清楚,怎么知道老是穿插一些汇编代码,调到int r1 = dfs(Abs(num-p1*ones[d]), d-1); 就看不清楚了= =......
这个代码我只能看懂一部分,希望有能之士看明白之后可以提点提点^_^...不过也好,知道自己有什么薄弱的地方赶快弥补弥补,这个递归总是要弄明白的,先放下这道题,苦练搜索题:dfs + bfs!!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 15 + 5; 9 LL ones[maxn], n; 10 11 void Init() 12 { 13 ones[0] = 1; 14 for (int i = 1; i < 16; i++) 15 ones[i] = ones[i-1] * 10 + 1; 16 } 17 18 LL Abs(LL tmp) 19 { 20 return (tmp < 0 ? -tmp : tmp); 21 } 22 23 LL dfs(LL num, int d) 24 { 25 if (d == 0) 26 return num; 27 int p1 = num / ones[d]; 28 int p2 = p1 + 1; 29 int r1 = dfs(Abs(num-p1*ones[d]), d-1); 30 int r2 = dfs(Abs(num-p2*ones[d]), d-1); 31 return min(p1*(d+1)+r1, p2*(d+1)+r2); 32 } 33 34 int main() 35 { 36 while (scanf("%lld", &n) != EOF) 37 { 38 Init(); 39 cout << dfs(n, 15) << endl; 40 } 41 return 0; 42 }
调试版(VC6)(读者请忽略)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 15 + 5; 8 __int64 ones[maxn], n; 9 10 void Init() 11 { 12 ones[0] = 1; 13 for (int i = 1; i < 16; i++) 14 ones[i] = ones[i-1] * 10 + 1; 15 //for (int i = 0; i < 16; i++) 16 // cout << "ones[" << i << "] = " << ones[i] << endl; 17 } 18 19 __int64 Min(__int64 a, __int64 b) 20 { 21 return (a > b ? b : a); 22 } 23 24 __int64 Abs(__int64 tmp) 25 { 26 return (tmp < 0 ? -tmp : tmp); 27 } 28 29 __int64 dfs(__int64 num, int d) 30 { 31 if (d == 0) 32 return num; 33 int p1 = num / ones[d]; 34 int p2 = p1 + 1; 35 int r1 = dfs(Abs(num-p1*ones[d]), d-1); 36 int r2 = dfs(Abs(num-p2*ones[d]), d-1); 37 return Min(p1*(d+1)+r1, p2*(d+1)+r2); 38 } 39 40 int main() 41 { 42 while (scanf("%I64d", &n) != EOF) 43 { 44 Init(); 45 printf("%I64d ", dfs(n, 15)); 46 } 47 return 0; 48 }