标签:
如果只依靠上述的思路,写出来的程序要跑2.7s(上限是3s),所以属于刚刚好AC.
我们这里有很多种优化方法,我就说两个我用了的。
1. 寻找幂的时候,我们每次不应该从已得到数字里任意抽两个,这样效率很低。而且很容易出一道,我们每一次都是操作上一步得到的数字,所以这样只需要枚举另一个操作数就够了。
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int MAXD = 13; 5 int n, f[1<<(MAXD - 1)], maxd, a[15]; 6 7 bool dfs(int d) { 8 if (a[d] == n) return true; 9 if (d < maxd && (a[d]<<(maxd - d)) >= n) { 10 for (int i = d; i >= 0; i--) 11 for (int j = 0; j < 2; j++) { 12 int nextn = j ? a[d] + a[i] : a[d] - a[d - i]; 13 if (nextn <= 0 || f[nextn]) continue; 14 f[nextn] = 1; 15 if (nextn <= 0) continue; 16 a[d + 1] = nextn; 17 if (dfs(d + 1)) return true; 18 f[nextn] = 0; 19 } 20 } 21 return false; 22 } 23 int main() { 24 a[0] = 1; 25 while (scanf("%d", &n) == 1 && n) { 26 if (n == 1) { printf("0\n"); continue;} 27 for (maxd = 1; maxd < MAXD; maxd++) { 28 memset(f, 0, sizeof(f)); 29 f[1] = 1; 30 if (dfs(0)) break; 31 } 32 printf("%d\n", maxd); 33 } 34 return 0; 35 }
2.打表。
因为n的范围是1~1000, 所以我们可以用稍微慢一点的算法,提前算出来结果,保存到文件里,然后再粘贴到提交的代码里。
比如我的代码是
1 int main() { 2 freopen("ans_table", "w", stdout); 3 /* 4 some code. 5 */ 6 for(n = 1; n <= 1000; n++) { 7 if (n == 1) { printf("ans[%d] = 0;\n", i); continue;} 8 for (maxd = 1; maxd < MAXD; maxd++) { 9 /* 10 some code. 11 */ 12 if (dfs(0, 1)) break; 13 } 14 printf("ans[%d] = %d;\n", i, maxd); 15 } 16 return 0; 17 }
这样我们就本地生成了文件"ans_table"。
里面的答案都是形如
ans[1] = 0;
ans[2] = 1;
ans[3] = 2;
ans[4] = 2;
ans[5] = 3;
ans[6] = 3;
ans[7] = 4;
ans[8] = 3;
ans[9] = 4;
ans[10] = 4;
ans[11] = 5;
ans[12] = 4;
Power Calculus 快速幂计算 (IDA*/打表)
标签:
原文地址:http://www.cnblogs.com/Bowen-/p/4957843.html