搜索做法,21分,求提示(已加注释)
  • 板块P1120 小木棍
  • 楼主GLESENA
  • 当前回复2
  • 已保存回复2
  • 发布时间2022/7/24 21:40
  • 上次更新2023/10/27 18:34:48
查看原帖
搜索做法,21分,求提示(已加注释)
553772
GLESENA楼主2022/7/24 21:40

第一次做蓝题 ,果然太蓝了

21分, #3 #7 #11 #12 #14 #16 ~ #30RE ,

#9 #13 #15 WA ,

其他AC

以下是代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,a[66],bot[51];
bool dfs(ll s,ll cnt,ll l)//深搜
{//s是可能成立的答案,cnt记录已用过的木棍数,l记录若干拼接起来的木棍的长度
	if(cnt==n)//木棍用完时
	{
		return s==l;//若拼起来的木棍正好与答案等长,即答案成立,反之则不行
	}
	if(s==l)//如果木棍尚未用完,但已拼好了一截
	{
		l=0;//l归零,继续拼下一截
	}
	for(int i=51;i>=1;i--)//从长到短找可用的木棍(优化:短棍相对灵活,所以先放置不那么灵活的长棍)
	{
		if((bot[i]==0)||i>s-l)//如果没有可用的棍子(bot中存储了每一种长度的棍子的数量)或棍子太长放不进去
		continue;//就继续找(优化:如果在拼成当前长度为l的目标木棍时, 发现一根长度为i的木棍没用, 那剩下没用到的长度为i的木棍也没用)
		else//如果棍子符合标准
		{
			bot[i]--;//这种长度的棍子库存-1
			if(f(s,cnt+1,l+i))//递归搜索,cnt+1,即用掉的棍子数+1,l+i,即已拼成的棍子长度+1
			{
				return 1;//如果返回了true,就也返回true,把好消息传递下去
			}
			bot[i]++;//如果不行,就把那根棍子放回去,对应的bot[i]+1
		}
	}
}
int main()
{
	ll sum=0,mx=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sum+=a[i];//sum记录所有木棍的总长
		bot[a[i]]++;//bot相当于一个桶,储存每种长度的木棍的个数,搜索函数里要用,省下了排序的时间
		if(mx<a[i]) mx=a[i];//mx记下最长的小木棍
	}
	for(int i=mx;i<=sum;i++)//从小到大枚举可能的答案(优化:答案一定在mx与sum之间)
	{
		if(sum%i==0)//优化:所有木棍的总长度一定能被答案整除
		if(dfs(i,0,0))//搜索判断i是否是正解
		{//如果i是正解就输出然后结束程序
			cout<<i;
			return 0;
		}
	}
	return 0;
}

求大佬看一看

2022/7/24 21:40
加载中...