给出n(n<=1000)个考试的成绩ai和满分bi,要求去掉k个考试成绩,使得剩下的∑ai/∑bi*100最大并输出。

典型的01分数规划

要使∑ai/∑bi最大,不妨设ans=∑ai/∑bi,则∑ai-ans*∑bi=0。

设f[ans]=∑ai-ans*∑bi,我们要求一个ans的最大值,使得存在一组解,满足f[ans]=0,而其他的任意解都有f[ans]<=0(如果f[ans]>0,说明∑ai/∑bi>ans,即还有比ans更优的解),对于∑ai/∑bi,从0~1二分枚举答案,对于每一个枚举到的答案mid,如果f[mid]的最大值>0,则说明存在更大的ans,从mid~r里边进一步找更优的解。否则从l~mid中找。

如何求f[mid]的最大值,f[ans]=∑ai-ans*∑bi=∑(ai-ans*bi)

显然如果mid确定了,那么对于每个考试,ai-mid*bi的值也就确定,那么从大到小排序,取最大的n-m个数进行累加即可。

二分答案法 94MS

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define FOR(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
typedef long long LL;
int i,j,k,n,m,x,y,T,ans,big,cas,a[],b[];
bool flag;
double dp[],d[];
double run(double u)
{
double cur=;
for (int i=;i<=n;i++) d[i]=a[i]-u*b[i];
sort(d+,d++n);
for (i=m+;i<=n;i++) cur+=d[i];
return cur;
} int main()
{
while (scanf("%d%d",&n,&m),n+m)
{
for (i=;i<=n;i++) scanf("%d",&a[i]);
for (i=;i<=n;i++) scanf("%d",&b[i]);
double l=,r=;
while (r-l>eps)
{
double mid=(l+r)/;
if (run(mid)>) l=mid;
else r=mid;
}
printf("%d\n",(int)(r*+0.5));
}
return ;
}

Dinkelbach算法(牛顿迭代法) 32MS

事先随意确定一个数,然后逼近正确答案。

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<string>
#include<sstream>
#define eps 1e-9
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define FOR(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
typedef long long LL;
struct node
{
double num;
int i;
}d[];
int i,j,k,n,m,x,y,T,big,cas,a[],b[];
bool flag;
double l,ans;
LL p,q;
bool cmp(node a,node b)
{
return a.num<b.num;
}
int main()
{
while (scanf("%d%d",&n,&m),n+m)
{
for (i=;i<=n;i++) scanf("%d",&a[i]);
for (i=;i<=n;i++) scanf("%d",&b[i]);
l=;ans=;
while (fabs(l-ans)>eps)
{
ans=l;
for (i=;i<=n;i++)
{
d[i].num=a[i]*1.0-l*b[i];
d[i].i=i;
}
sort(d+,d++n,cmp);
p=q=;
for (i=m+;i<=n;i++)
{
p+=a[d[i].i];
q+=b[d[i].i];
}
l=p*1.0/q;
}
printf("%d\n",(int)(ans*+0.5));
}
return ;
}

注意Dinkelbach算法中p,q要使用long long

POJ 2976 Dropping tests 01分数规划的更多相关文章

  1. POJ 2976 Dropping tests 01分数规划 模板

    Dropping tests   Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6373   Accepted: 2198 ...

  2. $POJ$2976 $Dropping\ tests$ 01分数规划+贪心

    正解:01分数规划 解题报告: 传送门! 板子题鸭,,, 显然考虑变成$a[i]-mid\cdot b[i]$,显然无脑贪心下得选出最大的$k$个然后判断是否大于0就好(,,,这么弱智真的算贪心嘛$T ...

  3. POJ - 2976 Dropping tests(01分数规划---二分(最大化平均值))

    题意:有n组ai和bi,要求去掉k组,使下式值最大. 分析: 1.此题是典型的01分数规划. 01分数规划:给定两个数组,a[i]表示选取i的可以得到的价值,b[i]表示选取i的代价.x[i]=1代表 ...

  4. POJ 2976 Dropping tests(分数规划)

    http://poj.org/problem?id=2976 题意: 给出ai和bi,ai和bi是一一配对的,现在可以删除k对,使得的值最大. 思路: 分数规划题,可以参考<挑战程序竞赛> ...

  5. [poj 2976] Dropping tests (分数规划 二分)

    原题: 传送门 题意: 给出n个a和b,让选出n-k个使得(sigma a[i])/(sigma b[i])最大 直接用分数规划.. code: //By Menteur_Hxy #include & ...

  6. Dropping tests(01分数规划)

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8176   Accepted: 2862 De ...

  7. [poj2976]Dropping tests(01分数规划,转化为二分解决或Dinkelbach算法)

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

  8. POJ2976 Dropping tests —— 01分数规划 二分法

    题目链接:http://poj.org/problem?id=2976 Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  9. poj Dropping tests 01分数规划---Dinkelbach算法

    果然比二分要快将近一倍.63MS.二分94MS. #include <iostream> #include <algorithm> #include <cstdio> ...

随机推荐

  1. C语言的printf输出格式控制

    C语言的printf输出格式控制 printf大家都耳熟能详,但是能真正将其用法弄透的估计很少见. 转一篇,改天整理. 1.转换说明符 %a(%A)     浮点数.十六进制数字和p-(P-)记数法( ...

  2. golang io需要牢记的几个点

    对于Reader比较麻烦需要记住以下: When Read encounters an error or end-of-file condition after successfully readin ...

  3. Fedora21源配置与显卡安装

    1. 安装fastestmirror Fedora的源速度很慢,令人很烦恼,不过它有个自动选最快的源包. yum install yum-fastestmirror yum-presto 它会判断你的 ...

  4. 实现跨线程访问UI控件的3种方法

    namespace 多线程 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } privat ...

  5. php解析json数据

    <?php $data; $data.="["; for ($i=0;$i<20;$i++) { $data.="{"; $data.=" ...

  6. unset() isset() empty difined()操作变量详解

    isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] )  功能:检测变量是否设置 返回值:  若变量不存在则返 ...

  7. 关于Chrome(谷歌浏览器)对docume,准确获取网页客户区的宽高、滚动条宽高、滚动条Left和Top

    对于document.compatMode,很多朋友可能都根我一样很少接触,知道他的存在却不清楚他的用途.今天在ext中看到 document.compatMode的使用,感觉这个对于我们开发兼容性的 ...

  8. B题(覆盖问题)

        B - B   Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u   Desc ...

  9. Egret 文本处理

    常规处理: private createGameScene():void { var shp = new egret.Shape(); shp.graphics.beginFill(0xff0000, ...

  10. NSIndexSet-入门浅析

    NSIndexSet-入门浅析   记得上一次,用到,关于删除UITableView分组的方法 [tableView deleteSections:[NSIndexSet indexSetWithIn ...