大致思路 (以下称原始木棍为大木棍,拆分后的为小木棍) 易知大木棍长度在小木棍的最大长度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 条评论

目前还没有评论...