97pts求调,有注释,马蜂自认为良好,玄一关
  • 板块P1120 小木棍
  • 楼主Dexember
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/6/22 12:07
  • 上次更新2025/6/22 23:04:35
查看原帖
97pts求调,有注释,马蜂自认为良好,玄一关
1413688
Dexember楼主2025/6/22 12:07
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){return a>b;}
int n;
int a[70];
int vis[70];
int nxt[70];//下一个长度不相同的木棍 
int sum;
bool da=false;//是否输出了答案 
int lk;//目标长度 
void dfs(int x,int nl,int last)//在拼第x根木棒,已拼起来的长度为nl,上一根木棍的编号 
{
	if(nl>lk)
	{
		return;
	}
	if(nl==lk)//拼上了 
	{
		if(x==sum/lk)//拼完了 
		{
			da=true;
			cout<<lk;
			exit(0);
		}
		else
		{
			int p;
			for(p=1;p<=n;++p)
			{
				if(!vis[p])
				{
					break;
				}
			}
			vis[p]=1;
			dfs(x+1,a[p],p);
			vis[p]=0;
		}
	}
	else
	{
		for(int i=last+1;i<=n;++i)//优化:如果上次用了这一根,下次用的只能比上一根更短 
		{
			if(!vis[i]&&a[i]<=(lk-nl))//这根木棍没用过并且可以用进去 
			{
				vis[i]=1;
				dfs(x,nl+a[i],i);
				vis[i]=0;
				
				//到这其实说明拼失败了
				//如果这一根拼失败了,那么所有和他长度相同的都会拼失败 
				if(lk-nl==a[i]||lk-nl==lk)
				{
					return;
				}
				i=nxt[i]; 
				if(i==n)//已经再也不能拼成功了 
				{
					return;
				}
			}
		}
	}
}
int main()
{
	cin>>n;
	int ed=0;
	a[0]=0x3f;
	for(int i=1;i<=n;++i)
	{
		cin>>a[i];
		ed+=a[i];
	}
    
	sum=ed;
	sort(a+1,a+1+n,cmp);
	nxt[n]=n;
	for(int i=n-1;i>=1;--i)
	{
		if(a[i]==a[i+1])
		{
			nxt[i]=nxt[i+1];
		}
		else
		{
			nxt[i]=i;
		}
	}
	int st=a[1];
	for(int i=st;i<=ed/2;++i)
	{
		if(ed%i!=0)
		{
			continue;
		}
		lk=i;
		dfs(1,0,1);
	}
	if(!da)
	{
		cout<<sum;
	}
	return 0;
}
/*
9
5 2 1 5 2 1 5 2 1
6

4
1 2 3 4
5
*/

2025/6/22 12:07
加载中...