- 题解
小木棍
- 2025-10-14 22:38:09 @
大致思路 (以下称原始木棍为大木棍,拆分后的为小木棍) 易知大木棍长度在小木棍的最大长度maxLen与所有小木棍的和sum之间 对于每个长度都进行尝试,肯定会超时,需要排除一些答案和剪枝 如何排除一部分答案? 对于尝试的大木棍长度len,要满足sum%len==0,可以根据这点排除一部分答案 如何剪枝? 1.第一次拼接不成功,直接返回。 2.拼接时可以跳过重复的小木棍长度。 3.对于此次拼接成功的,但后续拼接失败的,直接返回。
用visited数组标记使用过的小木棍
using namespace std;
#define int long long
vector<int> v;
vector<bool> visited;
int sum = 0;
int n;
bool dfs(int len,int cnt,int start,int currLen) {
if (cnt*len==sum) return true;
if (currLen==len) return dfs(len,cnt+1,0,0);
for (int i=start;i<n;i++) {
if (visited[i]==false&&currLen+v[i]<=len) {
visited[i]=true;
if (dfs(len,cnt,i+1,currLen+v[i])) return true;
visited[i]=false;
if (currLen+v[i]==len) break;
if (currLen==0) return false;
while (i<n-1 && v[i]==v[i+1]) i++;
}
}
return false;
}
void solve() {
sum=0;
cin >> n;
v.resize(n);
visited.assign(n,false);
int maxLen=0;
for (int i = 0; i < n; i++) {
cin >> v[i];
sum += v[i];
if (v[i] > maxLen) maxLen = v[i];
}
sort(v.begin(), v.end(),greater<int>());
int res=sum;
for (int i = maxLen; i<sum ; i++) {
if (sum%i!=0) continue;
if (dfs(i,0,0,0)) {
res=i;
break;
}
}
cout << res << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t=1;
while (t--)solve();
}```
0 条评论
目前还没有评论...