洛谷试炼场P1120(搜索Ex)

题目:详见https://www.luogu.org/problemnew/show/P1120

解题思路:深搜其实和枚举类似,但是加上剪枝,能让运算时间大大减小

#include<bits/stdc++.h>
using namespace std;
int cnt,s[100],use[100],ct;
bool cmp(int x,int y)
{
	return x>y;
}
void dfs(int sum,int ans,int target,int st)
{
	if(ans==0)
	{
		printf("%d", target);
        exit( 0 );
	}
	if(sum==target)
	{
		dfs(0,ans-1,target,0);//如果达到预期,就进行下一轮拼接 
		return;
	}
	if(s[cnt-1]>target-sum) return;
	for(int i=st;i<cnt;i++)
	{
		if(!use[i]&&s[i]+sum<=target)
		{
			use[i]=1;
			dfs(sum+s[i],ans,target,i+1);
			use[i]=0;
			if(sum+s[i]==target||sum==0) break;//如果能组成一组却不可行或者有一组行不通直接退出
			while(s[i]==s[i+1])i++;//如果是s[i]==s[i+1] ,那么s[i] 没成功,s[i+1]就更不可能成功! 
		}
	}
}
int main()
{
	//freopen("t.txt","r",stdin);
	int n,t;
	scanf("%d",&n);
	cnt=0;
	int sum=0,ma=-1;
	memset(use,0,sizeof(use));
	while(n--)
	{
		scanf("%d",&t);
		if(t<=50)
		{
			s[cnt++]=t;
			sum+=t;
			if(t>ma) ma=t;
		}
	}
	sort(s,s+cnt,cmp);
	for(int i=ma;i<=sum/2;i++)
	{
		if(sum%i) continue;
		dfs(0,sum/i,i,0);
	}
	printf("%d\n",sum);
	return 0;
 } 

猜你喜欢

转载自blog.csdn.net/qq_39861441/article/details/89488581