POJ - 2976 Dropping tests (01分数规划)

终于把01分数规划这个坑填上了。

题意是有二维平面上的n个向量$(a_i,b_i)$,让你选择其中的m个,使得这些向量和的斜率,即$\frac{\sum a_i}{\sum b_i}$最小。

二分斜率,设$\frac{\sum a_i}{\sum b_i}\geqslant k$,即$\sum a_i\geqslant \sum kb_i$,即$\sum a_i-kb_i\geqslant 0$,选择$a_i-kb_i$前m大的向量判断是否大于0即可。

每次交POJ都得和CE刚上一番...

 1 #include<cstdio>
 2 #include<functional>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 typedef double db;
 7 const int N=1000+10,inf=0x3f3f3f3f;
 8 int n,k,a[N],b[N];
 9 db c[N];
10 bool ok(db x) {
11     db sum=0;
12     for(int i=0; i<n; ++i)c[i]=a[i]-x*b[i];
13     sort(c,c+n,greater<db>());
14     for(int i=0; i<k; ++i)sum+=c[i];
15     return sum>=0;
16 }
17 db bi(db l,db r) {
18     for(int i=0; i<100; ++i) {
19         db mid=(l+r)/2;
20         ok(mid)?l=mid:r=mid;
21     }
22     return l;
23 }
24 int main() {
25     while(scanf("%d%d",&n,&k),n) {
26         k=n-k;
27         for(int i=0; i<n; ++i)scanf("%d",&a[i]);
28         for(int i=0; i<n; ++i)scanf("%d",&b[i]);
29         printf("%.0f\n",bi(0,1)*100);
30     }
31     return 0;
32 }

 

上一篇:初中|代数辅导


下一篇:从知乎摘录的不等式练习