【hdoj_1009】FatMouse's Trade
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1009<
本题用到贪心策略和结构体排序。
问题简化:现有资本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; //都为0
else 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的更多相关文章
- 【HDU】3401:Trade【单调队列优化DP】
Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 【单调队列优化dp】HDU 3401 Trade
http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...
- WEB网络问题的排查【转】
Browser/Server结构主要是利用了不断成熟的Web浏览器技术:结合浏览器的多种脚本语言和ActiveX技术,用通用浏览器实现原来需要复杂专用软件才能实现的强大功能,同时节约了开发成本.B/S ...
- plantuml使用教程【转】
plantuml使用教程[转] Table of Contents 前言 什么是PlantUML 在Emacs里配置PlantUML(参考:Run it from Emacs) 其他软件里的Pla ...
- 【03】Html书写规范
[03] Html书写规范 1.推荐使用html5的文档声明 <!DOCTYPE HTML> 2.必须申明文档的编码charset,且与文件本身编码保持一致,推荐使用UTF-8编码 ...
- 【Java】阿里巴巴开发规范手册
Java 开发手册 一. 编程规约 (一) 命名风格 [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例: _name, $name, __name [强制]代码中 ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
随机推荐
- springMVC前后台数据交互
假设项目需求是在springMVC框架下,后台要传送一个list到前台,那我们就要做以下几个步骤: 1 在web.xml文件中进行springMVC的配置: <?xml version=&quo ...
- CSS position属性---absolute与relative
详情请点击此链接 http://www.cnblogs.com/polk6/archive/2013/07/26/3214847.html
- 【SSH】——Hibernate三种状态之间的转化
Hibernate的三种状态为:transient.persistent和detached.对这三种状态的理解可以结合Session缓存,在Session缓存中的状态为persistent,另外两种不 ...
- [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段
multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...
- 变量可以通过into赋值
- 不使用库函数、自己编写的(strlen、strcpy、strcmp、strcat、memcmp、memcpy、memmove)
不使用库函数.自己编写的(strlen.strcpy.strcmp.strcat.memcmp.memcpy.memmove) //求字符串长度的函数 int my_strlen(const char ...
- Str 函数
Str 函数 Visual Studio 2005 返回数字的 String 表示形式. Public Shared Function Str(ByVal Number As Object) ...
- COGS 497——奶牛派对
奶牛派对 我们发现每头牛需要走的路程即为它到x的最短路+x到它的最短路. 转化: 于是这道题变成了一道典型的单源最短路问题,只需求出每个点到x的最短路dl,以及从x到此点的最短路d2,然后去找max( ...
- Codeforce 721C DP+DAG拓扑序
题意 在一个DAG上,从顶点1走到顶点n,路径上需要消费时间,求在限定时间内从1到n经过城市最多的一条路径 我的做法和题解差不多,不过最近可能看primer看多了,写得比较复杂和结构化 自己做了一些小 ...
- [洛谷P3765]总统选举
题目大意:有$n(n\leqslant5\times10^5)$个数,有$m(m\leqslant5\times10^5)$次询问. 一次询问形如$l\;r\;s\;k\;w_1\;w_2\dots ...