您的位置:首页 > 其它

POJ3045 Cow Acrobats 二分搜索

2014-07-17 20:51 309 查看
题目大意是N头牛,每头牛重量wi,力量si,现在这些牛以某种顺序踩在其它牛身上堆积成垂直的一个高度。每头牛滑落的风险为在它身上所有其他牛的重量减去它的力量。现在需要计算出最大的一头的风险最小值是多少。

这题可以用二分搜索进行求解。设C(X):=最大一头牛的风险不超过X。问题是如何判断C(X)是否成立。初始时可以保存每头牛驼上其他所有牛的风险。对于X,最底下的牛肯定是选择风险最小的牛,当选择了这头牛作为最底下的牛时,其它所有牛的风险都会减少相同的值,因此,他们的大小关系都不变,所以只需要排一次序,然后每次都选择风险最小的牛从下往上放就可以了。

#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>

using namespace std;

struct Weight
{
int weight;
int strength;
};

int compp(const void* a1, const void* a2)
{
Weight* w1 = (Weight*)a1;
Weight* w2 = (Weight*)a2;
if (w1->strength == w2->strength)
{
return w2->weight - w1->weight;
}
else
return w1->strength - w2->strength;
}

Weight weight[50001];

bool CC(int x, int n)
{
int curdis = 0;
for (int i = 0; i < n; i++)
{
if (weight[i].strength - curdis > x)
{
return false;
}
else
curdis += weight[i].weight;
}
return true;
}

int main()
{
int n;
#ifdef _DEBUG
freopen("e:\\in.txt", "r", stdin);
#endif
scanf("%d\n", &n);
int totalw = 0;
int maxstrength = 0;
for (int i = 0; i < n;i++)
{
scanf("%d %d\n", &weight[i].weight, &weight[i].strength);
totalw += weight[i].weight;
if (maxstrength < weight[i].strength)
{
maxstrength = weight[i].strength;
}
}
for (int i = 0; i < n; i++)
{
weight[i].strength = totalw - weight[i].strength - weight[i].weight; //每头牛驼起其它所有牛的风险
}
qsort(weight, n, sizeof(Weight), compp);
int l = -(1 + maxstrength);
int r = totalw + 1;
while (r - l > 1)
{
int mid = (r + l) / 2;
if (CC(mid, n))
{
r = mid;
}
else
l = mid;
}
printf("%d\n", r);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: