社区讨论
不同的做法求剪枝
P1120[CERC 1995] 小木棍参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lzxitdxd
- 此快照首次捕获于
- 2024/08/17 10:30 2 年前
- 此快照最后确认于
- 2024/08/17 13:03 2 年前
以下为本人的做法,想到了几种剪枝但都收效甚微, 喜提 TLE 36 分。
CPP#include<bits/stdc++.h>
using namespace std;
const int N=70;
int n,a[N],sum,maxn,t[N],k,s[N];
//t数组存当前每根长木棍的长度,k是枚举的长度,s是排序后的后缀和
bool f;//是否有解
void dfs(int x,int cnt,int tot){
//x是当前的木棍编号,cnt是已经有几根长木棍(不一定拼好了),tot是拼好了几根
if(f)return;
if(x==n+1){
if(tot==sum/k)f=1;
//如果所有的木棍都拼好了,说明有解
return;
}
for(int i=1;i<=cnt;i++){
if(t[i]+a[x]<=k){
t[i]+=a[x];
dfs(x+1,cnt,tot+(t[i]==k));
t[i]-=a[x];
if(f)return;
}
}
if(s[x]<k)return;
//如果后面所有的木棍加上当前的长度都不够,说明无解
//如果当前所有的木棍都跟它拼不了,就自己单独新开一个
t[cnt+1]=a[x];
dfs(x+1,cnt+1,tot+(a[x]==k));
t[cnt+1]=0;
if(f)return;
}
int main(){
ios::sync_with_stdio(NULL);
cin.tie(NULL);cout.tie(NULL);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
maxn=max(maxn,a[i]);
}
sort(a+1,a+n+1,greater<int>());
for(int i=n;i>=1;i--){
s[i]=s[i+1]+a[i];
}//求后缀和
for(int i=maxn;i<=sum/2;i++){
//枚举木棍长度
if(sum%i==0){
f=false;
k=i;
dfs(1,0,0);
if(f){
cout<<i;
return 0;
}
}
}
cout<<sum;
return 0;
}
翻遍了题解区都没有找到类似的做法。烦请各位大佬看一下我的方法有没有问题,如果没有问题请各位大佬帮忙剪枝一下。回者必关,谢谢!
回复
共 3 条回复,欢迎继续交流。
正在加载回复...