POJ 2976 Dropping tests【0/1分数规划模板】

传送门:http://poj.org/problem?id=2976

题意:给出POJ 2976 Dropping tests【0/1分数规划模板】POJ 2976 Dropping tests【0/1分数规划模板】POJ 2976 Dropping tests【0/1分数规划模板】,去掉POJ 2976 Dropping tests【0/1分数规划模板】对数据,使得POJ 2976 Dropping tests【0/1分数规划模板】的总和除以POJ 2976 Dropping tests【0/1分数规划模板】的总和最大。

思路:0/1分数规划

POJ 2976 Dropping tests【0/1分数规划模板】,则POJ 2976 Dropping tests【0/1分数规划模板】POJ 2976 Dropping tests【0/1分数规划模板】(其中POJ 2976 Dropping tests【0/1分数规划模板】等于0或1)

开始假设POJ 2976 Dropping tests【0/1分数规划模板】使得上式成立,将POJ 2976 Dropping tests【0/1分数规划模板】从大到小排序,只取前POJ 2976 Dropping tests【0/1分数规划模板】个(这样一定是最优的),若所得和大于0,则表示POJ 2976 Dropping tests【0/1分数规划模板】偏小,反之偏大。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const double eps = 1e-7;
int a[1005];
int b[1005];
double s[1005];
int n, k;
double solve(double x)
{
for(int i = 1; i <= n; i++)
s[i] = a[i] - x * b[i];
sort(s + 1, s + 1 + n);
double sum = 0;
for(int i = k + 1; i <= n; i++)
sum += s[i];
return sum;
}
int main()
{
while(~scanf("%d%d", &n, &k) && (n + k))
{ for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; i++)
scanf("%d", &b[i]);
double l = 0, r = 1;
double mid ;
while((r - l) > eps)
{
mid = (l + r) / 2;
if(solve(mid) > 0)
{
l = mid;
}
else
{
r = mid;
}
}
printf("%0.lf\n", mid * 100 );
}
return 0;
}
上一篇:读书笔记--SQL必知必会15--插入数据


下一篇:poj 3155 二分+最小割求实型最小割(最大密集子图)