[洛谷] P1120 小木棍 [数据加强版]

题目大意

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050。

现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。

给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

题目解析

搜索加剪枝

剪枝:

1、使用桶排,因为长度不超过50。
2、枚举的长度应该能整除总长度。
3、若当前搜索时已经使用了长度为 x x x 的木棍,则下次直接从长度为 x x x 从大到小枚举
4、若某次搜索拼接时,当前拼好的长度为0或当前长度加上先前枚举的长度等于需要长度,直接跳出循环

代码

#include<bits/stdc++.h>
using namespace std;
int n,ai,sum,maxl,minl;
int a[70],b[70];
void dfs(int lev,int now,int len,int pos)
{
	if(lev==0)
	{
	  cout<<len;
	  exit(0);
	}
	if(now==len)
	{
	  dfs(lev-1,0,len,maxl);
	  return;
	}
	for(int i=pos;i>=minl;i--)
	 if(a[i]&&i+now<=len)
	 {
	   a[i]--;
	   dfs(lev,i+now,len,i);
	   a[i]++;
	   if(!now||now+i==len) 
	    break; 
	 }
}
int main()
{
	scanf("%d",&n);
	for(int x,i=1;i<=n;i++)
	{
	  scanf("%d",&x);
	  if(x<=50) a[x]++,sum+=x,maxl=max(maxl,x),minl=min(minl,x);
	}
	for(int i=maxl;i<=sum;i++)
	 if(sum%i==0)
	  dfs(sum/i,0,i,maxl);
	cout<<sum;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值