P2240 【深基12.例1】部分背包问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
解题思路
1.创建结构体变量,储存每堆金币的单位价格和重量,金币的单位价格就是这堆金币的总价值除以总重量,这样就可以保证拿到价值尽可能多的金币
2.将数组a按单位价格进行降序排序
3.从数组a的第一项开始遍历,可以保证拿到的金币价值最高,设置一个变量sum表示当前书包里金币的重量,设置一个变量num表示当前是第几项
4.sum++,第num项的金币重量--, 如果num项的金币数量为0,num++
5.如果sum和书包承重量相等,退出循环
代码
#include<bits/stdc++.h>
using namespace std;
struct gold{
double t;
int w;
}a[105];//结构体变量
bool cmp(gold a,gold b)
{
return a.t>b.t;//单位价格高的在前
}//对比函数
int main()
{
int n,t,m,v,sum=0,num=1;
double s=0;
cin>>n>>t;
for(int i=1;i<=n;i++)
{
cin>>m>>v;
a[i].t=double(v*1.0/m);//储存单位价格
a[i].w=m;//储存重量
}
sort(a+1,a+n+1,cmp);//排序
while(sum<t)//如果达到书包承重量,退出循环
{
if(a[num].w==0)
{
num++;
}//第num堆金币拿完了
sum++;//每轮拿重量为1的金币
a[num].w--;
s+=a[num].t;//拿走的金币总价值
}
printf("%.2lf",s);//保留两位小数输出
return 0;
}