您的位置:首页 > 其它

51Nod-1257-背包问题 V3

2017-04-14 13:05 246 查看
ACM模版

描述



题解

典型的0-1分数规划,二分单位体积价值即可。

0-1分数规划
属于较简单易学的算法,本以为
背包问题 V3
一定是一个更难的动态规划,谁知道只是一个二分。不懂
0-1分数规划
的可以看看参考一栏的 blog,其实很简单的,只要知道
0-1分数规划
,这个题可以算是5级题比较简单的问题了。

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>

using namespace std;

const int MAXN = 5e4 + 10;
const double ESP = 1e-6;

int N, K;

struct article
{
int W, P;
double unit;
} atc[MAXN];

int gcd(int a, int b)
{
if (b == 0)
{
return a;
}
return gcd(b, a % b);
}

int cmp(article a, article b)
{
return a.unit > b.unit;
}

int charge(int &x, int &y, double m)
{
for (int i = 0; i < N; i++)
{
atc[i].unit = atc[i].P - atc[i].W * m;
}
sort(atc, atc + N, cmp);

x = y = 0;
double temp = 0;
for (int i = 0; i < K; i++)
{
x += atc[i].P;
y += atc[i].W;
temp += atc[i].unit;
}

if (temp >= 0)
{
return 1;
}
else
{
return 0;
}
}

int main(int argc, const char * argv[])
{
cin >> N >> K;
for (int i = 0; i < N; i++)
{
scanf("%d%d", &atc[i].W, &atc[i].P);
}

double left = 0, right = MAXN, mid;
int z = 0, m = 0, x, y;
while (fabs(right - left) > ESP)
{
mid = (left + right) / 2;
if (charge(x, y, mid))
{
left = mid;
z = x;
m = y;
}
else
{
right = mid;
}
}

int temp = gcd(z, m);
z /= temp;
m /= temp;
printf("%d/%d\n", z, m);

return 0;
}


参考

《0-1分数规划》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分 0-1分数规划