题意:n个数字,k个箱子,然后是很关键的一个点,一个箱子只能放1或者2个数字,问箱子的最大容量是多少。
做法:这道题是二分这我当时想到了,但我没有看到一个箱子最多只能放2个数这个条件。我们分的是最大容量。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,k;
ll a[maxn];
bool check(ll x)
{
int cnt=0;
for(int i=1;i<=n;i++)
if(a[i]>x)
return false;
int head=1,tail=n;
while(head<=tail){
if(a[head]+a[tail]<=x) head++,tail--,cnt++;
else tail--,cnt++;
}
if(cnt>k) return false;
else return true;
}
ll binary(ll l,ll r)
{
ll mid,ans=0;
while(l<=r)
{
mid=l+(r-l)/2;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
return ans;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
cout<<binary(1,2e6+10)<<endl;
}
另一种做法是直接贪心。假设a,b,c三个数,并且a<b<c,若有2个箱子,为了尽可能让箱子的容量小,肯定选a+b,c因为a+b<a+c.
当然还有一个分情况讨论,题目中给出n<=2*k,但我们要分n是否<=k的情况
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,k;
ll a[maxn];
ll sum;
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
if(n<=k)
{
for(int i=1;i<=n;i++)
sum=max(sum,a[i]);
cout<<sum<<endl;
return 0;
}
int len=k*2-n;
for(int i=n;i>=n-len;i--) sum=max(sum,a[i]);
len=n-len;
for(int i=1;i<=len/2;i++)
sum=max(sum,a[i]+a[len-i+1]);
cout<<sum<<endl;
}