1. 程式人生 > >poj 3111 二分水題

poj 3111 二分水題

題意:有n個物品的重量和價值分別是w[i]和v[i],從中選出K個物品使得單位重量的價值最大

貪心的反例是顯然的,nyoj的樣例就是

本題是個二分的很好例子,可以理解成二分得到一個閾值,然後判斷是否夠k個,以此得到最優解,而這個正確性也是顯然的

#include <cstdio>  
#include <stdlib.h>  
#include <iostream>  
#include <algorithm>  
#define rep(i, j, k) for(int i = j; i <= k; i++)

using namespace std;  

const int INF=0x3f3f3f3f;  
int n,k;  

struct cadongllas
{  
    double v,w,tmp;  
    int id;  
}s[100005];  

bool cmp(cadongllas x,cadongllas y)
{
    return x.tmp>y.tmp;  
}  


bool judge(double d)
{  
    double sum = 0;
	rep (i, 1, n)
    	s[i].tmp=s[i].v-d*s[i].w;  
	sort (s + 1, s + 1 + n, cmp);
	rep (i, 1, k)
    	sum+=s[i].tmp;  
    return sum>=0;  
} 

int main()
{  
    while(scanf("%d%d",&n,&k)!=EOF){  
		rep (i, 1, n)
			scanf ("%lf%lf", &s[i].v, &s[i].w), s[i].id = i;
        double l = 0, r = 0x7fffffff * 1.0;
		rep (i, 0, 101)
		{  
            double mid=(l+r)/2;  
            if(judge(mid))  
            	l=mid;  
            else  
            	r=mid;  
        }  
		rep (i, 1, k)
        	printf("%d ",s[i].id);  
        printf("\n");  
    }  
    return 0;  
}