#include<iostream>#include<bits/stdc++.h>#include<cctype>#include<cmath>#include<algorithm>usingnamespacestd;typedeflonglongLL;#define Check(a, b) (a >= 0 && a < h && b >= 0 && b < w) intT,N,M,sum=0;intArr[100];voidsolve();intmain(){#ifndef ONLINE_JUDGEfreopen("a.txt","r",stdin);#endifcin>>T;for(inti=0;i<T;i++){cout<<"case #"<<i<<":\n";solve();}}voidsolve(){cin>>N>>M;sum=0;intmaxn=0;for(inti=0;i<N;i++)cin>>Arr[i];for(inti=0;i<N;i++){for(intj=i+1;j<N;j++){for(intk=j+1;k<N;k++){sum=Arr[i]+Arr[j]+Arr[k];if(sum>maxn&&sum<=M)maxn=sum;}}}cout<<maxn<<endl;}
才看到N <= 100,直接暴力就好了……为什么要写算法呢……为什么呢……
题目有bug,应该是1<=m<=300000,不是30000吧!否则一直Runtime Error啊!
一种做法
include
using namespace std;
int T,n,m;
vector V;
int find(int aa,int bb)
{
int val=m-V[aa]-V[bb];
int left=0,right=V.size()-1,ans=-1;
while(left<=right)
{
int mid=(left+right)/2;
if(V[mid]<=val)
{
if(mid!=aa && mid!=bb) ans=max(ans,V[mid]+V[aa]+V[bb]);
left=mid+1;
}
else right=mid-1;
}
return ans;
}
int main()
{
cin>>T;
for(int step=0;step>n>>m;
V.clear();
for(int i=1;i<=n;i++)
{
int xx;
cin>>xx;
V.push_back(xx);
}
sort(V.begin(),V.end());
int ans=-1;
for(int i=0;i<V.size();i++)
for(int j=i+1;j<V.size();j++)
if(V[i]+V[j]<m) ans=max(ans,find(i,j));
printf(“case #%d:\n%d\n”,step,ans);
}
return 0;
}
一个数组上选择三个不同位置的数,使得三个数的和在不超过M的前提下最大,求最大值
明摆着,出题人是想要我们枚举两个数,二分查找第三个数
而二分查找的前提是排序完成。
复杂度为nnlog(n)
当然,还有一种做法,当做背包问题来做,不过一般的背包问题,只能决定有几个物体供选择,而不能决定实际上选择了几个
背包写的有点想吐了。以后有心情再来写。
二分查找?需要二分查找吗……感觉完全不用,附C代码:
不会吧不会吧,这道naive还有人写了很久吗,太简单了吧!
想到一个笑话……
既然有库函数,还自己写排序干嘛
同理?
既然不会超时,还花时间写背包,排序,贪心干嘛……
mmp