『POJ 2976』Dropping tests (01分数规划)

题目链接

Descrip

In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be

.

Given your test scores and a positive integer k, determine how high you can make your cumulative average if you are allowed to drop any k of your test scores.

Suppose you take 3 tests with scores of 5/5, 0/1, and 2/6. Without dropping any tests, your cumulative average is . However, if you drop the third test, your cumulative average becomes .

题目描述

现在有n个物品,每个物品都有两个价值,一个价值为\(a\),一个价值为\(b\),(保证\(a_i\leq b_i\))现在最多可以有k个物品不选,请问能够使选择的物品的\(100*\frac{\sum a_i}{\sum b_i}\)最大是多少?

解题思路

显然是一道01分数规划的题目,因为题目中说明了\(a_i\leq b_i\),那最终的取值就只能是\(0\)到\(100\)之间,所以我们把那个100提出来,答案的区间就变成了\([0,1]\),所以,我们可以二分答案去验证可行性。

数学证明

假设\(\frac{\sum a_i}{\sum b_i}\ge x\),那就有\(\sum a_i\ge x*\sum b_i\),即\(\sum a_i-x*\sum b_i\ge0\),我们只要处理出每个物品\(i\)的另一个价值\(a_i-x*b_i\),然后从大到小排序,计算前\(n-k\)个物品的价值的和,是否大于等于0就好了。

一点小细节

注意一下eps的设置就好了。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1050;
const double eps=1e-5;
int n,k;
int a[maxn],b[maxn];
double tmp[maxn];
inline bool cmp(double x,double y){
    return x>y;
}
inline bool check(double x){
    for(register int i=1;i<=n;i++){
        tmp[i]=(double)a[i]-1.0*b[i]*x;
    }
    sort(tmp+1,tmp+1+n,cmp);
    double ans=0;
    for(register int i=1;i<=n-k;i++)ans+=tmp[i];
    return ans>=0;
}
int main(){
    while(~scanf("%d%d",&n,&k)){
        if(n+k==0)return 0;
        for(register int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(register int i=1;i<=n;i++)scanf("%d",&b[i]);
        register double l=0.0,r=1.0;
        while(r-l>eps){
            register double m=(l+r)/2;
            if(check(m))l=m;
            else r=m;
        }
        l*=100;
        printf("%.0lf\n",l);
    }
}

原文地址:https://www.cnblogs.com/Fang-Hao/p/9650615.html

时间: 2024-10-08 23:37:03

『POJ 2976』Dropping tests (01分数规划)的相关文章

POJ - 2976 Dropping tests (01分数规划)

终于把01分数规划这个坑填上了. 题意是有二维平面上的n个向量$(a_i,b_i)$,让你选择其中的m个,使得这些向量和的斜率,即$\frac{\sum a_i}{\sum b_i}$最小. 二分斜率,设$\frac{\sum a_i}{\sum b_i}\geqslant k$,即$\sum a_i\geqslant \sum kb_i$,即$\sum a_i-kb_i\geqslant 0$,选择$a_i-kb_i$前m大的向量判断是否大于0即可. 每次交POJ都得和CE刚上一番... 1

[poj2976]Dropping tests(01分数规划,转化为二分解决)

题意:有n场考试,给出每场答对的题数a和这场一共有几道题b,求去掉k场考试后,公式.的最大值 解题关键:01分数规划,double类型二分的写法(poj崩溃,未提交) 或者r-l<=1e-3(右边是精度) #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> #defi

POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】

题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11526   Accepted: 3930 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big ci

[POJ 2728]Desert King(0-1分数规划/最优比率生成树)

Description David the Great has just become the king of a desert country. To win the respect of his people, he decided to build channels all over his country to bring water to every village. Villages which are connected to his capital village will be

poj 2976 基础01分数规划

这个题算是01分数规划的最基本的应用了, 01分数规划是给你n对数(a1, b1)....(an, bn), 然后让你选择一些数对, 使得sigma(ai)/sigma(bi)最大.这里附上讲解一份, http://blog.csdn.net/hhaile/article/details/8883652, 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostre

POJ 2728 Desert King (最优比率生成树---01分数规划)

题目地址:POJ 2728 01分数规划的应用之一-最优比率生成树. 跟普通的01分数规划类似,只是这题的验证函数改成了最小生成树来验证.弱用的迭代法. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map>

poj 2718 最优比例生成树(01分数规划)模板

/* 迭代法 :204Ms */ #include<stdio.h> #include<string.h> #include<math.h> #define N 1100 #define eps 1e-10 #define inf 0x3fffffff struct node { int u,v,w; }p[N]; double ma[N][N]; double distance(int i,int j) { return sqrt(1.0*(p[i].u-p[j].u

poj 3621 Sightseeing Cows(最优比例生成环,01分数规划)

http://poj.org/problem?id=3621 大致题意:给出一个有向图,每个点都有一个点权,每条有向边也都有一个边权,要求出一个环使得环中点权之和与边权之和的比值最大. 思路:和最优比率生成树异曲同工.设点权是v[i],边权是e[i].不同的是这里一个是点,一个是边.怎么像生成树一样把这两个值放到一起呢?可以把他们都转化到边上.同样的二分λ,每次给边重新赋权为v[i] - λ*e[i](v[i]是该边终点的点权).因为要求比值最大,那么在这前提下于图中的所有环都<=0, 所以我们

POJ 2728 Desert King(最优比率生成树 01分数规划)

http://poj.org/problem?id=2728 题意: 在这么一个图中求一棵生成树,这棵树的单位长度的花费最小是多少? 思路: 最优比率生成树,也就是01分数规划,二分答案即可,题目很简单,因为这题是稠密图,所以用prim算法会好点. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector>