Yougth的最大化
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗?
-
输入
-
有多组测试数据
每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和Vi。
(1<=k=n<=10000) (1<=Wi,Vi<=1000000)
输出
- 输出使得单位价值的最大值。(保留两位小数) 样例输入
-
3 2 2 2 5 3 2 1
样例输出
-
0.75
-
帮助资料。
-
我的代码:
-
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int w[10010],v[10010]; double cnt[10010]; int n,k; int fun(double mid)//0-1分数规划 { int i; double sum; for (i=0;i<n;++i) { cnt[i]=v[i]-mid*w[i];//cnt数组是随着mid的增大而单调减的 } sort(cnt,cnt+n); for (sum=0,i=n-1;i>=n-k;--i) //之所以要找最大的k个数是因为sum有可能<0,不符合二分找sum趋近于0的思想 { sum+=cnt[i]; } return sum>=0?1:0; } double BS(double R)//二分搜索最大的单位价值 { double L=0,mid; while (R-L>0.00001) //二分法很久没用,竟然忘了R-L>0.00001为条件,用了L<=R结果死循环了 //L<=R是在数组中用的 { mid = ( L + R)/2; if (fun(mid)) { L=mid; } else { R=mid; } } return mid; } int main() { int i; double max; while (~scanf("%d %d",&n,&k)) { max=0; for (i=0;i<n;++i) { scanf("%d %d",&w[i],&v[i]); max = max > v[i]*1.0/w[i] ? max : v[i]*1.0/w[i] ;//找出最大的单位价值,做二分上界 } printf("%.2lf\n",BS(max)); } return 0; }
标程: -
#include <cstdio> #include <algorithm> #include <cmath> const double exps = 1e-3; struct node{ int v,w; double c; }; node p[10010]; int n,k; bool cmp(const node &x,const node &y){ return x.c > y.c; } double test(){ double ans,tmp = 0; int x,y; while(true){ ans = tmp; for(int i = 0; i < n; i++) p[i].c = p[i].v - ans*p[i].w; std::sort(p,p+n,cmp); x = y = 0; for(int i = 0; i < k; i++){ x += p[i].v; y += p[i].w; } tmp = x*1.0/y; if(fabs(tmp - ans) < exps) return ans; } } int main(){ while(~scanf("%d %d",&n,&k)){ for(int i = 0; i < n; i++) scanf("%d %d",&p[i].w,&p[i].v); printf("%.2f\n",test()); } return 0; }
-
有多组测试数据