题目大意:求最构成的最小的矩形面积,高为最长的那个高,宽为所有宽度加起来,其中可以有小于n/2个人躺下。
思路:这边将所有人按照,人的身高与宽的差值去降序排列,然后枚举高就可以了。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include <cstdio>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>q;
struct pos
{
int w, h;
int dis;
bool operator<(pos b)
{
return dis>b.dis;
}
int id;
}p[1100];
int main()
{
int n;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
{
scanf("%d%d", &p[i].w, &p[i].h);
p[i].dis = p[i].w - p[i].h;
q.push_back(p[i].w);
q.push_back(p[i].h);
p[i].id = -1;
}
sort(q.begin(), q.end());
sort(p, p + n);
//枚举高
int ans = 0x7fffffff;
for (int i = 0; i < q.size(); i++)
{
int sum = 0, cnt = 0;
bool flag = true;
for (int j = 0; j < n; j++)
{
//假如原来的高大于我们这时候所枚举的高,那么他就需要躺下。
if (p[j].h>q[i])
{
sum += p[j].h;
cnt++;
//躺下之后,他原来的宽大于此时我们枚举的高,说明我们这时候所枚举的高能够做高。自然结束
if (p[j].w > q[i])
{
flag = false;
break;
}
//给这个做上标记,表示他在i做高的时候已经躺下了。
p[j].id = i;
}
}
//这个时候躺下的人已经等于一半或者超过一半,或者是i不能做高,则应该枚举下一个
if (cnt> n / 2 || !flag)continue;
//继续寻找剩下的需要躺下的人
for (int j = 0; j < n; j++)
{
//剩下的所有人的情况都是高小于所枚举的高。
//不需要躺下的条件是他的宽度大于我们现在所枚举的高。或者是他的宽度小于他本身的高,或者趟的人已经够了
if (p[j].id == i)
continue;
if (p[j].w>q[i] || cnt +1> n / 2 || p[j].w < p[j].h)sum += p[j].w;
else
{
sum += p[j].h;
cnt++;
}
}
ans = min(ans, q[i] * sum);
}
printf("%d\n", ans);
}
}