题目名字 洛谷P2240 最多的金币
题意
一共n堆金子,承重力为t的背包来装,每一堆金子重m,价值v,要在t范围内装最多的金子,金子可以切割,输出要保留两位小数
思路
- 用结构体来表示每一堆金子,m和v,因为可以切割,所以需要计算单价,用bool排序使金子们为递减的形式,单价最高的放前面
- 用weight来表示最终袋子里面的价值
- 在袋子可以装下的情况下,不断将排在前面的金子放入袋子里,如果袋子还没装满而后一堆的金子放不下去,那就切割,用剩下空间的重量×单机,break,并计算最终袋子的价值
坑点
- 最后保留2位小数,需要用#include这个头文件,和输出需要用到fixed和setpricision(2)也不算个坑点,主要是第一次遇到不会写,啊哈哈哈哈,知识+1
- 在计算单价的时候需要先用a[i].v*1.0变成浮点运算,要不然算出来会自动舍去小数点后面的数!!比较容易忽略的点
算法一:结构体+贪心
代码
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
int n,t;
double weight;
struct node{
int m,v;
double per;
}a[105];
bool cmp(node a,node b)
{
return a.per>b.per;
}
int main(){
cin>>n>>t;
for(int i=1;i<=n;i++){
cin>>a[i].m>>a[i].v;
a[i].per=a[i].v*1.0/a[i].m;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
if( a[i].m<=t){
weight+=a[i].v;
t-=a[i].m;
}
else if(a[i].m>t){
weight+=a[i].per*t;
break;
}
}
cout<<fixed<<setprecision(2)<<weight;
return 0;
}
总结
学海无涯