您的位置:首页 > 其它

51nod 1257 背包问题 V3(分数规划)

2017-08-17 18:17 274 查看

  显然是分数规划...主要是不会求分数的形式,看了题解发现自己好傻逼QAQ

  还是二分L值算出d[]降序选K个,顺便记录选择时候的p之和与w之和就可以输出分数形式了...

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=500010,inf=1e9;
struct poi{double sum;int pos;}d[maxn];
int n,K,ansx,ansy,x,y;
int p[maxn],w[maxn];
double mid;
void read(int &k)
{
int f=1;k=0;char c=getchar();
while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
k*=f;
}
bool cmp(poi a,poi b){return a.sum-b.sum>1e-6;}
bool check()
{
for(int i=1;i<=n;i++)d[i].sum=1.0*p[i]-1.0*mid*w[i],d[i].pos=i;
sort(d+1,d+1+n,cmp);
double sum=0.0;x=y=0;
for(int i=1;i<=K;i++)
{
x+=p[d[i].pos];y+=w[d[i].pos];
sum+=d[i].sum;
}
if(sum>=0)return 1;
return 0;
}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
int main()
{
read(n);read(K);
for(int i=1;i<=n;i++)read(w[i]),read(p[i]);
double l=0,r=50000;
while(r-l>1e-6)
{
mid=(l+r)/2;
if(check())l=mid,ansx=x,ansy=y;
else r=mid;
}
ll d=gcd(ansx,ansy);
printf("%lld/%lld",ansx/d,ansy/d);
return 0;
}
View Code

 

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