题意:
解法:
求 最 优 策 略 下 的 lim t − > ∞ g ( t ) t 由 于 t − > ∞ , 因 此 每 个 人 物 遇 到 的 次 数 是 相 同 的 , 问 题 可 以 转 化 为 从 每 个 人 物 那 里 选 择 一 个 任 务 , 使 得 ∑ g ∑ t 最 大 , 显 然 01 分 数 规 划 , 二 分 ∑ g ∑ t 的 值 m i d , c h e c k 的 条 件 为 ∑ g ∑ t > = m i d , 变 换 一 下 : ∑ g ∑ t − m i d > = 0 ∑ g − ∑ t ∗ m i d > = 0 ∑ ( g − t ∗ m i d ) > = 0 对 于 每 个 人 物 , 有 ( g 1 , t 1 ) 和 ( g 2 , t 2 ) 两 个 任 务 选 择 , 为 了 使 得 尽 可 能 满 足 上 式 , 显 然 选 择 g − t ∗ m i d 较 大 的 . 假 设 算 法 二 分 k 次 , 那 么 复 杂 度 为 O ( k ∗ n ) . 求最优策略下的\lim_{t->\infty} \frac{g(t)}{t}\\ 由于t->\infty,因此每个人物遇到的次数是相同的,\\ 问题可以转化为从每个人物那里选择一个任务,使得\frac{\sum g}{\sum t}最大,\\ 显然01分数规划,\\ 二分\frac{\sum g}{\sum t}的值mid,check的条件为\frac{\sum g}{\sum t}>=mid,\\ 变换一下:\\ \frac{\sum g}{\sum t}-mid>=0\\ \sum g-\sum t*mid>=0\\ \sum (g-t*mid)>=0\\ 对于每个人物,有(g1,t1)和(g2,t2)两个任务选择,\\ 为了使得尽可能满足上式,显然选择g-t*mid较大的.\\ 假设算法二分k次,那么复杂度为O(k*n). 求最优策略下的t−>∞limtg(t)由于t−>∞,因此每个人物遇到的次数是相同的,问题可以转化为从每个人物那里选择一个任务,使得∑t∑g最大,显然01分数规划,二分∑t∑g的值mid,check的条件为∑t∑g>=mid,变换一下:∑t∑g−mid>=0∑g−∑t∗mid>=0∑(g−t∗mid)>=0对于每个人物,有(g1,t1)和(g2,t2)两个任务选择,为了使得尽可能满足上式,显然选择g−t∗mid较大的.假设算法二分k次,那么复杂度为O(k∗n).
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e6+5;
int a[maxm];
int b[maxm];
int c[maxm];
int d[maxm];
int n;
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
}
double ans=0;
double l=0,r=1e9;
for(int kk=0;kk<100;kk++){
double mid=(l+r)/2;
double sum=0;
for(int i=1;i<=n;i++){
double x=b[i]-mid*a[i];
double y=d[i]-mid*c[i];
sum+=max(x,y);
}
if(sum>=0){
ans=mid,l=mid;
}else{
r=mid;
}
}
printf("%.10f\n",ans);
return 0;
}