2 solutions
-
0
忘记重置n的值了,警示后人using namespace std; int n, a[111], cnt, len; bool v[111]; bool dfs(int sum, int leng, int last){ if(sum == cnt) return true; if(leng == len) return dfs(sum + 1, 0, 0); int val = 0; for(int i=last;i<n;i++){ if(v[i]) continue; if(a[i] == val) continue; if(leng + a[i] > len) continue; v[i] = 1; if(dfs(sum, leng + a[i], i + 1)) return true; v[i] = 0; val = a[i]; if(!leng || len == leng + a[i]) return false; }return false; } int main(){ while(cin>>n){ if(!n) return 0; int maxx = 0, sum = 0, tot = 0; for(int i=0;i<n;i++){ int x; cin>>x; if(x>50) continue; sum += x; a[tot++] = -x; maxx = max(maxx, x); } n = tot; // 忘记重置n的值了 sort(a, a + n); for(int i=0;i<n;i++) a[i] = -a[i]; for(len=maxx;len<=sum;len++){ if(sum % len) continue; cnt = sum / len; memset(v, 0, sizeof v); if(dfs(0, 0, 0)) break; } cout<<len<<endl; } }
-
0
#include <bits/stdc++.h> using namespace std; int a[100], v[100], n, len, cnt; // 正在拼第stick根原始木棒(已经拼好了stick-1根) // 第stick根木棒的当前长度为cab // 拼接到第stick根木棒中的上一根小木棍为last bool dfs(int stick, int cab, int last) { // 所有原始木棒已经全部拼好,搜索成功 if (stick > cnt) return true; // 第stick根木棒已经拼好,去拼下一根 if (cab == len) return dfs(stick + 1, 0, 1); int fail = 0; // 剪枝 // 剪枝(1):小木棍长度递减(从last开始枚举) for (int i = last; i <= n; i++) if (!v[i] && cab + a[i] <= len && fail != a[i]) { v[i] = 1; if (dfs(stick, cab + a[i], i + 1)) return true; fail = a[i]; v[i] = 0; // 还原现场 if (cab == 0 || cab + a[i] == len) return false; // 剪枝 } return false; // 所有分支均尝试过,搜索失败 } int main() { while (cin >> n && n) { int sum = 0, val = 0, m = 0; for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); if (x <= 50) { a[++m] = x; sum += a[m]; val = max(val, a[m]); } } n = m; sort(a + 1, a + n + 1); reverse(a + 1, a + n + 1); for (len = val; len <= sum; len++) { if (sum % len) continue; cnt = sum / len; // 原始木棒长度为len,共cnt根 memset(v, 0, sizeof(v)); if (dfs(1, 0, 1)) break; } cout << len << endl; } }
- 1
Information
- ID
- 483
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 10
- Tags
- # Submissions
- 12
- Accepted
- 2
- Uploaded By