题目大意:有n 个人,每个人有两个属性wi; hi,n 个人的价值和为wi的和*max(hi)
现在你可以让不超过⌊n2⌋ 个人的wi 与hi 值互换,求能得到的最小价值和
solution:
枚举最后方案中最大的h,设为maxh
若某个人i 的wi 与hi 均大于maxh 则此方案不可行
若某个人恰有一个属性大于maxh 则可确定他是否换属性
剩下的人按wi - hi 从大到小排序后贪心选择
O(n log n + n2)
这个题···提交无数次wa
细节还是有的,而且注意枚举的时候不能按h枚举
要从1到w和h中最大的数依次枚举
因为这个wa了好几遍0.0
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 1005
#define LL long long
using namespace std;
int n,num,sumw,mh,q[maxn],tot,mx;
LL ans;
inline int rd(){
int x=0,f=1; char c=' ';
while(c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();}
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
struct qwq{
int w,h;
}a[maxn];
bool cmp(int x,int y) {return x>y;}
LL check(int maxh){
int cnt=0,tmp=sumw;
tot=0; memset(q,0,sizeof q);//这个一开始还忘记加了···
for(int i=1;i<=n;i++){
if(a[i].w>maxh && a[i].h>maxh) return -1;
if(a[i].w<=maxh && a[i].h>maxh) tmp=tmp-a[i].w+a[i].h,cnt++;
if(cnt>num) return -1;
else if(a[i].w<=maxh && a[i].h<=maxh) q[++tot]=a[i].w-a[i].h;
}
sort(q+1,q+tot+1,cmp);//记得要按w-h排序
for(int i=1;i<=min(tot,num-cnt);i++){
if(q[i]>0) tmp-=q[i];
}
return 1LL*tmp*maxh;
}
int main(){
n=rd(); num=n/2;
for(int i=1;i<=n;i++){
a[i].w=rd(),a[i].h=rd();
sumw+=a[i].w; mh=max(mh,a[i].h); mx=max(mx,max(mh,a[i].w));
}//mdzz还得算一下mx
ans=1LL*sumw*mh;
for(int i=1;i<=mx;i++){//一开始是枚举所有的h,但应该从1到mx枚举
LL t=check(i);
if(t>=0) ans=min(ans,t);
}
printf("%lld\n",ans);
return 0;
}