01分数规划

很久以前学的,今天看到了又复习一遍。
普通01分数规划的核心只有一个式子,sigma(v)/sigma(c)>=x,由此可写出sigma(v-x*c)>=0。
结合二分,排序后取前k个相加,大于0即可。
放一道例题:https://ac.nowcoder.com/acm/problem/14662
AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int c[10005],v[10005];
int n,k;

bool check(int x){
    vector<int> a(n);
    for (int i=0;i<n;i++){
        a[i]=v[i]-x*c[i];
    }
    sort(a.begin(),a.end(),greater<int>());
    ll sum=0;
    for (int i=0;i<k;i++){
        sum+=a[i];
    }
    if (sum>=0) return 1;
    return 0;
}

void solve(){
    cin>>n>>k;

    for (int i=0;i<n;i++){
        cin>>c[i]>>v[i];
    }
    int l=0,r=10004;
    while (l<r){
        int mid= l+(r-l)/2;
        if (check(mid)){
            l=mid+1;
            
        }
        else
        r=mid;
    }
    cout<<l-1<<'\n';
    
}

int main(){
    int t;
    cin>>t;
    while (t--) solve();
    return 0;
}