藍書(演算法競賽進階指南)刷題記錄——POJ2976 Dropping tests(0-1分數規劃)
阿新 • • 發佈:2018-11-10
題目:POJ2976.
題目大意:給定你n組,讓你取出n-k組,使得這n-k組的a之和除以b之和最大.
這是一個經典的0-1分數規劃模型.
關於0-1分數規劃模型,一般就是確定一個標準值mid,發現:
若,那麼,也就是說.
同理,若,就是.
突然發現這個東西滿足二分性質.
所以我們就可以二分mid,然後判定這個式子的最大值是否會大於0.
判定的話找到最大的n-k組,算一下和,判斷和是否大於等於0即可.
程式碼如下:
#include<iostream> #include<cstdio> #include<map> #include<algorithm> using namespace std; #define Abigail inline void typedef long long LL; const double eps=1e-8; const int N=1000; int n,k; double c[N+9],a[N+9],b[N+9]; double l,r,mid; double check(double mid){ double sum=0.0; for (int i=1;i<=n;i++) c[i]=a[i]-mid*b[i]; sort(c+1,c+1+n); for (int i=n;i>k;i--) sum+=c[i]; return sum; } Abigail into(){ for (int i=1;i<=n;i++) scanf("%lf",&a[i]); for (int i=1;i<=n;i++) scanf("%lf",&b[i]); } Abigail work(){ l=0;r=1; while (l+eps<r){ mid=(l+r)/2.0; if (check(mid)>0) l=mid; else r=mid; } } Abigail outo(){ printf("%.0lf\n",100*r); } int main(){ while (scanf("%d%d",&n,&k),n+k){ into(); work(); outo(); } return 0; }
為什麼在POJ上用編譯器選G++掛了,C++就過了...
貌似C++輸出double需要%lf,G++上需要%f.