灵感来源于一篇文章:无聊的逗【蓝桥杯】-pudn.com
因为是从n个棍里选若干个,已经选过的棍不能再选,所以首先对数组序列进行排序,然后给所有元素赋一个状态,1为可用,0为不可用
如果要从n个棍里沾两个长度一样长并且最长的,所有每根沾棍的长度不可能比所有棍长度之和的一半长,所以舍弃那些不符合要求的棍,保持沾棍的长度小于等于所以棍长之和的一半,答案就出来了。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int sum(int arr[][15],int n); //求和函数声明
int n,sum2,arr[2][15],num=0,j=1; //sum2为数列和,num为最大长度 ,j为计数
cin>>n;
for(int i=0;i<n;i++){ //状态复制,1为可用,0为不可用
cin>>arr[0][i];
arr[1][i] = 1;
}
sort(arr[0],arr[0]+n); //排序
sum2 = sum(arr,n);
while(j<=n)
{
int i=n-j;
for(;i>=0;i--){
if(arr[0][i]>sum2/2){ //如果这根棍子比所有棍子和的一半还长,舍弃它
arr[1][i] = 0; //状态赋0
sum2 = sum(arr,n); //重新计算长度
continue;
}
if(arr[1][i]==1){ //如果状态为1,计算和
num += arr[0][i];
}
if(num>sum2/2){ //如果num加到比和的一半长了,减掉刚刚加的那根棍子,使num始终小于所有棍的一半
num -=arr[0][i];
continue;
}
arr[1][i] = 0;
}
j++;
}
cout<<num<<endl;
return 0;
}
int sum(int arr[][15],int n) //求和函数
{
int sum1=0;
for(int i=0;i<n;i++){
if(arr[1][i]==1)
sum1 += arr[0][i];
}
return sum1;
}