蓝桥杯 算法训练 无聊的逗

蓝桥杯 算法训练 无聊的逗

题目描述

  • 资源限制
    时间限制:1.0s 内存限制:256.0MB
  • 问题描述
    逗志芃在干了很多事情后终于闲下来了,然后就陷入了深深的无聊中。不过他想到了一个游戏来使他更无聊。他拿出n个木棍,然后选出其中一些粘成一根长的,然后再选一些粘成另一个长的,他想知道在两根一样长的情况下长度最长是多少。
  • 输入格式
    第一行一个数n,表示n个棍子。第二行n个数,每个数表示一根棍子的长度。
  • 输出格式
    一个数,最大的长度。
  • 样例输入
    4
    1 2 3 1
  • 样例输出
    3
  • 数据规模和约定
    n<=15

方案1 递归搜索 (存在左右两边重复搜索的情况)

#include<iostream>
#include<cmath>

using namespace std;

int n;				//n个棍子	
int stick[15];     //每个棍子的长度 
int MAX;		   //满足题意所能拼成的最大长度 
int sum;			//所有棍子的总长度 

//函数参数:假设分左右两边,左边棍子总长度L,右边棍子总长度R,棍子数组stick,棍子总数n,剩余棍子总长度rest,当前棍子索引cur 
//函数功能:在保证左右两边棍子相等的条件下,使左右两边棍子尽可能长 
void f(int L, int R, int stick[], int n, int rest, int cur){
	//当两边棍子之差大于剩余棍子总长度时,不可能满足左右两边棍子相等,结束递归 
	if(abs(L-R)>rest){
		return ;
	}
	
	//当两边棍子长度相等时,更新最大长度 
	if(L==R && MAX<L){
		MAX = L;
	}
	
	//当两边棍子长度不相等时,当前棍子有三种放置方法: 
	for(int i=cur; i<n; i++){
		//1.当前棍子放在左边 
		f(L+stick[i], R, stick, n, rest-stick[i], cur+1);
		//2.当前棍子放在右边 
		f(L, R+stick[i], stick, n, rest-stick[i], cur+1);
		//3.当前棍子舍弃 
		cur++;
	}
} 

int main(){
	cin>>n;
	for(int i=0; i<n; i++){
		cin>>stick[i];
		sum += stick[i]; 
	} 
	
	f(0, 0, stick, n, sum, 0);
	cout<<MAX<<endl;
	return 0; 
} 

方案2 数学公式(参考网上题解)

#include<iostream>
#include<algorithm>

using namespace std;

int n;				//n个棍子	
int stick[15];     //每个棍子的长度 
int MAX;		   //满足题意所能拼成的最大长度 
int sum;			//所有棍子的总长度 


int main(){
	cin>>n;
	for(int i=0; i<n; i++){
		cin>>stick[i];
		sum += stick[i]; 
	} 
	
	sum /= 2;
	
	sort(stick, stick+n);
	
	//  关键思想(我没证出来,但确实对了) 
	for(int i=n-1;i>=0;i--){
	   if(sum-MAX >= stick[i]){		//比较得出最大长度
			MAX += stick[i];
	   }
	}
	cout<<MAX<<endl;
	return 0; 
} 
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值