51nod-1257: 背包问题 V3

【传送门:51nod-1257


简要题意:

  给出n个物品,每个物品有它的体积和价值,要求选出k个物品,使得单位体积价值最大,求出最大单位体积价值


题解:

  01分数规划裸题

  直接01分数规划,然后对于true的情况就顺便记录一下选出来的物品的体积和,价值和就行了

  想着没写过01分数规划的博客,就顺便水一水。。


参考代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define eps 1e-5
using namespace std;
typedef long long LL;
double a[51000],b[51000];int n,k;
struct node
{
    double x;int t;
}c[51000];
bool cmp(node n1,node n2){return n1.x>n2.x;}
LL s1,s2;
bool check(double x)
{
    for(int i=1;i<=n;i++) c[i]=(node){a[i]-b[i]*x,i};
    sort(c+1,c+n+1,cmp);
    double ans=0.0;
    for(int i=1;i<=k;i++) ans+=c[i].x;
    if(ans>-eps)
    {
        s1=s2=0;
        for(int i=1;i<=k;i++) s1+=a[c[i].t],s2+=b[c[i].t];
        return true;
    }
    else return false;
}
LL gcd(LL a,LL b)
{
    if(a==0) return b;
    else return gcd(b%a,a);
}
int main()
{
    scanf("%d%d",&n,&k);
    double r=0.0;
    for(int i=1;i<=n;i++) scanf("%lf%lf",&b[i],&a[i]),r+=a[i];
    double l=0.0;
    while(r-l>eps)
    {
        double mid=(l+r)/2;
        if(check(mid)==true) l=mid;
        else r=mid;
    }
    LL G=gcd(s1,s2);
    printf("%lld/%lld\n",s1/G,s2/G);
    return 0;
}

 

posted @ 2018-10-10 09:33  Star_Feel  阅读(223)  评论(0编辑  收藏  举报