【hdoj_1009】FatMouse's Trade
来源:互联网 发布:淘宝七天退货时间计算 编辑:程序博客网 时间:2024/05/17 03:21
本题用到贪心策略和结构体排序。
问题简化:现有资本M,N个房间,第i个房间对应着价格为F[i]和收益J[i],需要将M全部花光去投资每个房间,使得收益最大,从每个房间中获取的效益与投入成正比,求最大获益。
贪心策略:由于成正比,收益与投资成正比,所以可以考虑“性价比”这个概念,把每个房间当作一个商品,则该商品的性价比=收益/价格,然后按照性价比从大到小排序,然后将资本M按顺序投资到每个房间,直到M为0或全部投资完。
将每个房间作为一个结构体变量,结构体含有数据成员:收益J和价格F。如何对结构体进行排序?只需要定义两个结构体是如何比较大小的即可,即需要说明:对结构体而言,>和<等不等符号分别是什么意思,因而要用到运算符重载。此处是按照 J/F的大小排序的,所以F不能为0,事实上,题目没有限制F是否为0,所以需要考虑F=0的情况。下面来看如何定义两个房间的大小关系的,用于运算符 > 的重载。
房间R1和R2:
R1.F=0且R2.F=0,这意味着,二者价格均为0,所以定义谁的收益大,谁就大。
R1.F!=0且R2.F=0,这意味着R2价格为0,所以定义R2大。(有可能R1和R2的收益均为0,那么二者就相等了,但实际投资过程中,当然不会投资R1和R2,所以定义R2比R1大还是相等不重要)
R1.F=0且R2.F!=0,这意味着R1价格为0,所以定义R1大。
R1.F!=0且R2.F!=0,这种情况,直接按照J/F定义R1和R2的大小即可。
用Dev-C++编写的C++代码:(提交之后AC)
#include <iostream>#include <iomanip>using namespace std;struct Room //定义结构体 {double J,F;//两个数据成员 Room(double j=0.0,double f=0.0) //构造函数,最好带有默认形参 {J = j;F = f;}void setRoom(double j,double f) //用于给结构体变量的两个数据成员赋值的函数 {J = j;F = f;}bool operator > (Room room) //运算符 > 的重载 {if (F==0 && room.F==0) return J > room.J; //都为0else if(F==0 && room.F!=0) return 1;else if(F!=0 && room.F==0) return 0;else return (J/F) > (room.J/room.F); //都不为0 }};void BinSort(Room *R,int N) //折半插入排序 {for(int i=1;i<N;i++){int low=0,high=i-1,mid;while(low<=high){mid = (low+high) / 2;if(R[i]>R[mid]) //此处用到了结构体之间 > 的关系,如果没有运算符 > 的重载会报错,这里用 > 而不用 < 使得排序是按照从大到小排序的 high = mid - 1;else low = mid + 1; }Room temp = R[i]; //这里用到结构体自带的赋值运算符,不用重载 for(int j=i;j>low;j--)R[j] = R[j-1];R[low] = temp;}}int main(){int M,N,k=0,kk=0;double J,F;double result[1000]; //存储最终结果 while(1){cin >> M >> N;if(M==-1 && N ==-1)break;else{double tot = 0.0; //用于记录结果,每次清零 Room *R = new Room[N]; //针对每组数据,开N个房间 for(int i=0;i<N;i++) //输入每个房间的两个参数,收益J和价格F {cin >> J >> F;R[i].setRoom(J,F);}BinSort(R,N); //排序 for(int j=0;j<N && M>0 ;j++) //逐个投资,直到投资完所有房间或者资本花光 {// 遇到第i个房间的两种可能情况if(M>=R[j].F) //一:资本足够 {M -= R[j].F; // 花掉了所需价格的资本 tot += R[j].J; // 获得的对应的全部收益 }else //二:资本不够 {M = 0; //资本花光tot += M/R[j].F*R[j].J; //按正比收益一部分 }}result[k++] = tot; // 记录结果 }}for(int i=0;i<k;i++)cout << setprecision(3) << fixed << result[i] << endl; return 0;}
说明:
1.如对折半插入排序算法有疑问,可以参考:
http://blog.csdn.net/ten_sory/article/details/51731823
2.在C++中将结果保留三位小数的方法,需要加载头文件#include<iomanip>,代码是:cout << setprecision(3) << fixed << 3.1415926 << endl;
如有纰漏,欢迎指正!
- 【hdoj_1009】FatMouse's Trade
- hdoj_1009 FatMouse' Trade
- FatMouse's Trade
- FatMouse's trade
- FatMouse's Trade
- HDU 1009 Fatmouse’s trade
- HDU 1009 Fatmouse's Trade
- 航院1009: FatMouse’s Trade
- 航院1009: FatMouse’s Trade
- HDU's ACM 1009 FatMouse' Trade
- ZOJ 2109 FatMouse's Trade(贪心)
- FatMouse' Trade
- FatMouse' Trade
- FatMouse' Trade
- FatMouse' Trade
- FatMouse' Trade
- FatMouse' Trade
- FatMouse' Trade
- CABasicAnimation 给layer改变颜色不起作用的原因
- Failed to load class "org.slf4j.impl.StaticLoggerBinder"问题解决fangan
- 万万没想到:用理工科思维理解世界
- Android系统透明栏(Translucent Bars)使用SystemBarTint的实现攻略
- View和ViewGroup的区别以及自定义控件步骤小结
- 【hdoj_1009】FatMouse's Trade
- 分析http应用层
- 时钟同步问题
- LeetCode-1- Two Sum
- 九度OJ 1009 二叉搜索树
- MFC线程的全面总结
- PHP的socket详解
- windows文件操作函数
- 8 固若金汤:网站的安全架构