POJ-3111
链接:http://poj.org/problem?id=3111
题目
这是一道 0/1 规划的变形,今天有人问怎么优化,然后就给写了一遍,感觉思路很巧妙,一样是根据表达式推出要贪心的关键属性然后再二分答案找到最大值。
代码
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
struct node
{
int id;
double v , w , c;
bool operator < (const node & t )const
{
return c > t.c ;
}
}p[N];
int n , m ;
bool check(double mid)
{
for(int i = 1; i <= n ; i ++)
{
p[i].c = p[i].v - mid * p[i].w;
}
sort(p+1,p+1+n);
double sum = 0 ;
for(int i = 1; i <= m ; i++)sum += p[i].c;
return sum >= 0 ;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m ;
for(int i = 1; i <= n ; i ++)
{
p[i].id = i ;
cin >> p[i].v >> p[i].w;
}
double l , r ;
l = -1, r = 1e7 ;
while(r - l > 1e-8)
{
double mid = (l + r)/2;
if(check(mid))l = mid;
else r = mid ;
}
for(int i = 1; i <= m; i ++)
cout << p[i].id <<' ';
}