题目大意是有3个数n,m,k。n 代表了序列的长度,m表示来回的次数,k表示最大的搬运量。一次可以搬运2个,现在求出在m次下,最大可以搬运的重量
思路:贪心的思想不用说了,主要说下multiset的用法
multiset<int>s,可以让s中的数有重复,并且自动对s进行升序
一些操作:
multiset<int>s
multiset<int> ::iterator it1,it2;//定义指针
it2=s.lower_bound(5),返回容器s中第一个不小于5的数字的下标位置.
还要注意的一点是s.begin()是第一个元素,s.end()是空的
代码:
#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
multiset<long long> s;
multiset<long long>::iterator it1,it2;
long long a[maxn];
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int T,kase,n,m,k;
scanf("%d",&T);
for(kase=1;kase<=T;kase++)
{
s.clear();
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++)
{
int num;
scanf("%d",&num);
if(num<=k)
{
s.insert(num);
}
}
int cnt=0;
while(true)
{
//cout<<"55"<<endl;
int sz=s.size();
if(sz<2)
break;
it1=s.end();
it1--;
long long fst=*it1;
s.erase(it1);
it2=s.lower_bound(min(fst,k-fst));
//cout<<*it2<<endl;
if(it2==s.end())
it2--;
if(it2==s.begin()&&*it2>(k-fst))
continue;
if(*it2<=k-fst)
{
a[cnt++]=*it2*fst;
s.erase(it2);
}
else
{
it2--;
a[cnt++]=*it2*fst;
s.erase(it2);
}
//cout<<a[cnt-1]<<endl;
}
sort(a,a+cnt,cmp);
long long ans=0;
for(int i=0;i<min(m,cnt);i++)
ans+=a[i];
printf("CASE #%d: %lld\n",kase,ans);
}
}