社区讨论

不同的做法求剪枝

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 条回复,欢迎继续交流。

正在加载回复...