1257 背包问题 V3——分数规划
N个物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数),从中选出K件物品(K <= N),使得单位体积的价值最大。
Input
第1行:包括2个数N, K(1 <= K <= N <= 50000)
第2 - N + 1行:每行2个数Wi, Pi(1 <= Wi, Pi <= 50000)
Output
输出单位体积的价值(用约分后的分数表示)。
Input示例
3 2
2 2
5 3
2 1
Output示例
3/4
————————————————————————————
第一眼看题目以为是贪心QAQ 后来发现不行
因为如果你现在已有的价值/体积是最佳
而现在有两个价值很小的物品 a b a价值比b大
但是a的体积远大于b的话 此时b肯定是更优的
所以正解应该是二分答案 判断是否合法就好辣
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int M=50007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,k; int c[M],w[M]; LL sumx,sumy,ansx,ansy; LL gcd(LL x,LL y){ while(y){ LL p=x%y; x=y; y=p; } return x; } struct node{double v; int pos;}e[M]; bool cmp(node a,node b){return a.v-b.v>1e-6;} bool check(double mid){ for(int i=1;i<=n;i++) e[i].v=1.0*w[i]-1.0*c[i]*mid,e[i].pos=i; sort(e+1,e+1+n,cmp); double sum=0; sumx=0; sumy=0; for(int i=1;i<=k;i++){ sum+=e[i].v; sumx+=w[e[i].pos]; sumy+=c[e[i].pos]; } return sum>=0; } int main() { n=read(); k=read(); for(int i=1;i<=n;i++) c[i]=read(),w[i]=read(); double l=0,r=50000; while(r-l>1e-6){ double mid=(l+r)/2; if(check(mid)) l=mid,ansx=sumx,ansy=sumy; else r=mid; } LL d=gcd(ansx,ansy); printf("%lld/%lld\n",ansx/d,ansy/d); return 0; }
分类:
二分——————
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· 终于决定:把自己家的能源管理系统开源了!
· [.NET] 使用客户端缓存提高API性能
· 外部H5唤起常用小程序链接规则整理
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· WPF 怎么利用behavior优雅的给一个Datagrid添加一个全选的功能