【传送门: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 ",s1/G,s2/G); return 0; }