题解:这道题之前用贪心写,没写出来,一直留在现在,今天回看了一下01分数规划才知道原来那个想法是错误的,简单来想一下,大概是因为物体的两个值是不可以约分的,这样的话就会导致每个物品值得权重不一样
就好比说原来是100/1,如果加上100000/99999,这样的话,之前一百所占得权重就微不足道了,还不如加上一个1/2.
所以正解应该是需要用到01分数规划的。
#pragma GCC optimize(3,"Ofast","inline") #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <math.h> #include <string> #include <list> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> #include <stdlib.h> #include <vector> #define maxn 100010 const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1e9 + 7; using namespace std; struct wazxy{ double val,wei; }a[maxn]; int n,k; double mid; struct rule{ bool operator ()(const wazxy & a,const wazxy & b){ return a.val-mid*a.wei>b.val-mid*b.wei; } }; bool check(){ sort(a,a+n,rule()); double ans=0; for(int i=0;i<k;i++) ans+=a[i].val-mid*a[i].wei; return ans>=0; } int main() { int t; cin>>t; while(t--){ cin>>n>>k; for(int i=0;i<n;i++){ scanf("%lf%lf",&a[i].wei,&a[i].val); } double l=0,r=1e9; double ans; while(r-l>=1e-6){ mid=(l+r)/2; if(check()){ ans=l; l=mid; } else r=mid; } printf("%.2f\n",ans); } return 0; }