01分数规划普通Dinkelbach算法

#include
using namespace std;
#define eps 1e-5
double m[50000+10],w[50000+10];
struct node{
double num;int ord;
} d[50000+10];
bool cmp(node a,node b){
return a.num>b.num;
}
int main(){
    int N,K;
    scanf("%d%d",&N,&K);
    for(int i=0;i

题意;有n场考试,给出每场答对的题数a和这场一共有几道题b,求选其中K场,

使公式 有最大值

Sample Input             Sample Output

3 2                                83.33

5 5

0 1

2 6

 

我们再次回到函数表达图:

01分数规划普通Dinkelbach算法_第1张图片

这个是二分的原理表现,在图中,我们取左界为0,右界为足够大,画出中间的(左+右)/2,发现此时F(r)max是大于0的,那么继续将左界移向(左+右)/2,继续二分,直到找到R为止。

 

Dinkelbach算法

我们换种思路,我们在判断一个当前的r的时候需要去求一个F(r)max,在二分之中我们仅仅判断了F(r)max与0的关系,这是利用率比较低的。其实我们可以将F(r)max利用起来。找到F(r)max所在的那一条直线,然后将r移动到这条直线的截距上面去(如下图,找到当前的F(r)max所在的直线,将r移动到r4上面去,这样做甚至只要2步即可到位)

它实质上是一种迭代,他是基于这样的一个思想:他并不会去二分答案,而是先随便给定一个答案,然后根据更优的解不断移动答案,逼近最优解。由于他对每次判定使用的更加充分,所以它比二分会快上很多。

在这个算法中,我们可以将r初始化为任意值,不过由于所有直线都只有y轴右边的部分,所以一般将r初始化为0。

01分数规划普通Dinkelbach算法_第2张图片

 

你可能感兴趣的:(ACM笔记-3图流)