不同的做法求剪枝
  • 板块P1120 小木棍
  • 楼主cqbzcjh
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/8/17 10:29
  • 上次更新2024/8/17 13:03:14
查看原帖
不同的做法求剪枝
906854
cqbzcjh楼主2024/8/17 10:29

以下为本人的做法,想到了几种剪枝但都收效甚微, 喜提 TLE 36 分。

#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;
}

翻遍了题解区都没有找到类似的做法。烦请各位大佬看一下我的方法有没有问题,如果没有问题请各位大佬帮忙剪枝一下。回者必关,谢谢!

2024/8/17 10:29
加载中...