01分数规划,简单的来说,就是有一些二元组(si,pi),从中选取一些二元组,使得∑si / ∑pi最大(最小)。

这种题一类通用的解法就是,我们假设x = ∑si / ∑pi的最大(小)值,那么就有x * ∑pi = ∑si ,即∑s - x * ∑pi= 0。也就是说,当某一个值x满足上述式子的时候,它就是要求的值。我们可以想到枚举……不过再想想,这个可以二分答案。

所以我们直接二分答案,当上述式子>0,说明答案小了,<0则说明答案大了,这样计算即可。

这是一种解决问题的方法,具体应该怎么做我们要看题来分析。

01分数规划有这样几种基本的题型(当然还有很多别的……暂时不在juruo的考虑范围内)

1.01分数规划

2.最优比率生成树

3.最优比率生成环

(当然还有什么最优比率最小割等等……不在juruo当前研究范围之内)

1.01分数规划。

基础题:poj2976

这个就是一开始说的这么一码事……选取n-k(原题是不选k)个物品使得比率最大。

我们考虑对上面的式子进行转化,之后我们只要给每个物品重新赋值为a - x*b,排序之后直接取前n-k大,判断这个值的正负性,然后按上面情况二分即可。

如果不大明白为什么是这么取得的,可以看这里(个人觉得很详细)

附上代码。

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')

using namespace std;
typedef long long ll;
const int M = 10005;
const int INF = 1000000009;
const double eps = 1e-6;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

struct test
{
   double a,b,d;
   bool operator < (const test &g) const
   {
      return d > g.d;
   }
}t[1005];

int n,k;
double L,R,ans,mid;

bool pd(double x)
{
   double cur = 0;
   rep(i,1,n) t[i].d = t[i].a - x * t[i].b;
   sort(t+1,t+1+n);
   rep(i,1,n-k) cur += t[i].d;
   return cur >= 0;
}

int main()
{
   while(1)
   {
      n = read(),k = read();
      if(!n && !k) break;
      rep(i,1,n) t[i].a = read();
      rep(i,1,n) t[i].b = read();
      L = 0,R = 1e10;
      while(fabs(R - L) > eps)
      {
     mid = (L + R) / 2.0;
     if(pd(mid)) L = mid;
     else R = mid;
      }
      printf("%.0lf\n",(mid * 100.0));
   }
   return 0;
}
View Code

相关文章:

  • 2021-08-31
  • 2022-03-05
  • 2021-09-06
  • 2021-05-26
  • 2022-03-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-09-29
  • 2021-10-12
  • 2021-10-21
相关资源
相似解决方案