标签:答案 div www eps struct 1.0 分数规划 family microsoft
第1行:包括2个数N, K(1 <= K <= N <= 50000)
第2 - N + 1行:每行2个数Wi, Pi(1 <= Wi, Pi <= 50000)
输出单位体积的价值(用约分后的分数表示)。
3 2 2 2
5 3
2 1
3/4
然后有:
即:
那么我们二分这个R,使等式的结果无限接近 0 即可
Emmmmm
(其实没推清楚)
Code代码
1 #include<stdio.h> 2 #include<math.h> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int n,k; 8 long long ansv,answ; 9 10 double eps = 0.000000001; 11 12 struct data{ 13 long long w,v; 14 double vrw; 15 }arr[1000000]; 16 17 bool cmp(const data &a,const data &b){ return a.vrw > b.vrw; } 18 19 bool check(long long &sumv,long long &sumw,double line){ 20 for(int i = 1;i <= n;i++) 21 arr[i].vrw = 1.0*arr[i].v-line*arr[i].w; 22 23 sort(arr+1,arr+1+n,cmp); 24 25 double tmp = 0; 26 sumv = 0,sumw = 0; 27 for(int i = 1;i <= k;i++) 28 sumv += arr[i].v, 29 sumw += arr[i].w, 30 tmp += arr[i].vrw; 31 32 return tmp >= 0; 33 } 34 35 long long gcd(long long a,long long b){ 36 if(a < b) swap(a,b); 37 return !b?a:gcd(b,a%b); 38 } 39 40 int main(){ 41 42 scanf("%d%d",&n,&k); 43 44 for(int i = 1;i <= n;i++) 45 scanf("%lld%lld",&arr[i].w,&arr[i].v); 46 47 double L = 0,R = 1000000; 48 long long sumv,sumw; 49 while(R-L > eps){ 50 // printf("%.8lf %.8lf\n",L,R); 51 double mid = (L+R)/2; 52 if(check(sumv,sumw,mid)) ansv = sumv, answ = sumw, L = mid; 53 else R = mid; 54 } 55 56 long long d = gcd(ansv,answ); 57 printf("%lld/%lld",ansv/d,answ/d); 58 59 return 0; 60 }
标签:答案 div www eps struct 1.0 分数规划 family microsoft
原文地址:http://www.cnblogs.com/Chorolop/p/7723055.html