2015-04-06 15:31:25
总结:以前做的一场,题目难度无序... 虽然时间有点久了,但是有道题必须得补!
比赛时只做了一题(E题),而且是队友提醒的... 算是道折半搜索吧
刚刚补了B题,一道贪心题,比赛时做出来被hack了,后来过了之后又被FST... 真是够糗的。
B题:
其实就是一道贪心题... 枚举矩形的高度,然后求出在该高度下矩形的最小宽度,枚举所有可能高度后取最优解即可。
思路很明显... (比赛时脑子实在是混... QAQ),对于当前枚举的高度,我们先扫描一遍必须“躺下”的人,并让他们躺下,如果
必须躺下的人数大于n/2,显然该高度不符合。然后我们考虑剩下的人,如果躺下能使总宽度变小那么这个人的 w > h,躺下可以
使宽度减少 w - h,那么我们对这些人按照(w-h)降序排序,尽量使他们躺下即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <string> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 15 #define MEM(a,b) memset(a,b,sizeof(a)) 16 #define REP(i,n) for(int i=0;i<(n);++i) 17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 18 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 19 #define MP(a,b) make_pair(a,b) 20 21 typedef long long ll; 22 typedef pair<int,int> pii; 23 const int INF = (1 << 30) - 1; 24 25 int n; 26 27 struct node{ 28 int w,h; 29 }nd[1010]; 30 31 bool cmp(node a,node b){ 32 return (a.w - a.h) > (b.w - b.h); 33 } 34 35 int main(){ 36 scanf("%d",&n); 37 for(int i = 1; i <= n; ++i){ 38 scanf("%d%d",&nd[i].w,&nd[i].h); 39 } 40 sort(nd + 1,nd + n + 1,cmp); 41 int ans = INF; 42 for(int h = 1; h <= 1000; ++h){ 43 int cnt = 0,sum = 0; 44 bool flag = true; 45 for(int i = 1; i <= n; ++i) if(nd[i].h >= nd[i].w){ //high person 46 if(nd[i].h > h){ 47 if(nd[i].w <= h && cnt < n / 2){ 48 cnt++; 49 sum += nd[i].h; 50 } 51 else{ 52 flag = false; 53 break; 54 } 55 } 56 else sum += nd[i].w; 57 } 58 if(flag == false) continue; 59 for(int i = 1; i <= n; ++i) if(nd[i].w > nd[i].h){ //wide person 60 if(nd[i].h > h){ 61 flag = false; 62 break; 63 } 64 if(nd[i].w <= h && cnt < n / 2){ 65 cnt++; 66 sum += nd[i].h; 67 } 68 else sum += nd[i].w; 69 } 70 if(flag) ans = min(ans,sum * h); 71 } 72 printf("%d\n",ans); 73 return 0; 74 }