这题...书上讲的有剧毒!
迭代加深对吧,书上写的是在DFS里枚举 i & j ,然而我狂T不止。
然后在学长的教导下发现每层DFS里只需枚举i即可,因为上一个数必须选。
因为不选上一个数的方案会在之前的DFS里搜到!
然后TM就16MS AC了。
我还想冲个榜,便打了一波表,结果因为空间太大而没能成功.....
1 #include <cstdio> 2 #include <cstring> 3 const int N = 110; 4 5 int a[N], lim; 6 int ans[N][N], use[N], ask[N * N]; 7 8 void out(int); 9 10 bool DFS(int k, int n) { 11 if(k == lim + 1) { 12 //printf("find: %d %d \n", a[lim], n); 13 if(a[lim] == n) { 14 for(int i = 1; i <= lim; i++) { 15 ans[n][i] = a[i]; 16 } 17 ans[n][0] = lim; 18 //printf("lim = %d\n", lim); 19 //out(n); 20 return 1; 21 } 22 return 0; 23 } 24 bool vis[N]; 25 memset(vis, 0, sizeof(vis)); 26 27 for(int i = k - 1; i >= 1; i--) { 28 int t = a[i] + a[k - 1]; 29 if(!vis[t] && t <= n) { 30 vis[t] = 1; 31 a[k] = t; 32 int f = DFS(k + 1, n); 33 if(f) { 34 return 1; 35 } 36 } 37 } 38 return 0; 39 } 40 41 inline void out(int n) { 42 //printf("out: %d %d ", n, ans[n][0]); 43 for(int i = 1; i <= ans[n][0]; i++) { 44 printf("%d ", ans[n][i]); 45 } 46 printf("\n"); 47 return; 48 } 49 50 inline void solve(int n) { 51 for(int i = 1; i <= n; i++) { 52 lim = i; 53 if(DFS(2, n)) { 54 return; 55 } 56 } 57 } 58 59 int main() { 60 int n, T = 0; 61 while(scanf("%d", &n) && n) { 62 /*for(n = 1; n <= 100; n++) { 63 memset(a, 0, sizeof(a)); 64 a[1] = 1; 65 solve(n); 66 */ 67 ask[++T] = n; 68 } 69 a[1] = 1; 70 for(int i = 1; i <= T; i++) { 71 if(!use[ask[i]]) { 72 use[ask[i]] = 1; 73 solve(ask[i]); 74 } 75 out(ask[i]); 76 } 77 78 return 0; 79 }