洛谷P4377 (0/1分数规划)
题目链接:https://www.luogu.com.cn/problem/P4377
0/1分数规划模板题
不少于\(W\),那就把所有大于 \(W\) 的答案都加到 \(W\) 上
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1010;
const ll INF = 1ll << 58ll;
const double eps = 1e-6;
int n,W;
int t[maxn],w[maxn];
ll f[maxn];
bool check(int x){
fill(f,f+1+W,-INF);
f[0] = 0;
for(int i=1;i<=n;++i){
for(int j=W;j>=0;--j){
int J = min(W,j+w[i]);
f[J] = max(f[J],f[j] + t[i] - 1ll * x * w[i]);
}
}
if(f[W] >= 0) return 1;
else return 0;
}
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
n = read(), W = read();
for(int i=1;i<=n;++i){
w[i] = read(), t[i] = read(); t[i] *= 1000;
}
int l = 0, r = 1000000;
while(l < r){
int mid = (l+r) / 2;
if(check(mid)){
l = mid + 1;
}else{
r = mid;
}
}
printf("%d\n",l-1);
return 0;
}