您的位置:首页 > 其它

POJ 3111 K Best <最大化平均,二分>

2016-08-08 22:13 330 查看
传送门:http://poj.org/problem?id=3111

题意:给你n个物品的重量和价值wi和vi。从中选出k个物品使得单位重量最大,输出序号

分析:最大化平均+二分

这是一道很经典的问题。。。

ac代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define max(x,y) (x>y?x:y)
#define INF 2147483674
const int maxn = 100005;
const double eps = 1e-9;
int n,k;
int w[maxn],v[maxn];
double y[maxn];

struct node
{
int id;
double yy;
bool operator < (const node& nod) const
{
return yy > nod.yy;
}
} no[maxn];

void solve()
{
double lb = 0.0,ub = INF,mid;
while(ub-lb>eps)
{
mid = (lb+ub)*1.0/2;
for(int i=0; i<n; i++)
{
no[i].yy = v[i] - mid*w[i];
no[i].id = i+1;
}
sort(no,no+n);
double sum = 0;
for(int i=0; i<k; i++)
{
sum +=no[i].yy;
}
if(sum > 0)lb=mid;
else
ub = mid;
}
for(int i=0; i<k; i++)
{
printf("%d",no[i].id);
if(i<k-1) printf(" ");
else
printf("\n");
}
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=0; i<n; i++)
{
scanf("%d %d",&v[i],&w[i]);
}
solve();
return 0;
}


第二份

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include <queue>
using namespace std;
const double INF=1e10;
const double eps=1e-6;
const int maxn=100005;
struct jewel
{
int v,w,id;
};
int n,k;
jewel jewels[maxn];
double y[maxn];
bool C(double x)
{
for(int i=0;i<n;i++)
{
y[i]=(double)jewels[i].v-x*jewels[i].w;
}
sort(y,y+n);
double sum=0;
for(int i=0;i<k;i++)
{
sum+=y[n-i-1];
}
return sum>=0;
}
double solve()
{
double lb=0,ub=INF,mid;
while(ub-lb > eps)
{
mid=(lb+ub)/2;
if(C(mid)) lb=mid;
else ub=mid;
}
return mid;
}
int main()
{
while(cin>>n>>k){
priority_queue<pair<double,int> > p;
for(int i=0;i<n;i++)
{
scanf("%d%d",&jewels[i].v,&jewels[i].w);
jewels[i].id=i;
}
double v=solve();
for(int i=0;i<n;i++)
{
p.push(make_pair(jewels[i].v-v*jewels[i].w,jewels[i].id));
}
k--;
for(int i=0;i<k;i++)
{
printf("%d ",p.top().second+1);
p.pop();
}
cout<<p.top().second+1<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: