【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的多线程处理的实现.而 ...
随机推荐
- Android EditText 限制输入字符
今天为简单的登录界面的输入框(用户名.密码框,验证码),均为EditText框,做输入限制,不能有空格,不能有一些特殊字符,不多说,直接上代码: /** * 禁止EditText输入空格 * * @p ...
- Intellij IDEA 系统路径配置
在使用IDEA启动Tomcat的时候,会读取系统路径,默认路径可能不是我们想要的,可以修改 C:\MyPrograms\IntelliJ IDEA 14.0.1\bin\idea.properties ...
- Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)
跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include&l ...
- CF985F Isomorphic Strings
题目描述 You are given a string s s s of length n n n consisting of lowercase English letters. For two g ...
- hbase(0.94) get、scan源码分析
简介 本文是需要用到hbase timestamp性质时研究源码所写.内容有一定侧重.且个人理解不算深入,如有错误请不吝指出. 如何看源码 hbase依赖很重,没有独立的client包.所以目前如果在 ...
- [CF620E]New Year Tree
题目大意:有一棵以$1$为根的有根树,有$n$个点,每个节点初始有颜色$c_i$.有两种操作: $1 v c:$将以$v$为根的子树中所有点颜色更改为$c$ $2 v:$ 查询以$v$为根的子树中的节 ...
- BZOJ 4710 [Jsoi2011]分特产 解题报告
4710 [Jsoi2011]分特产 题意 给定\(n\)个集合,每个集合有相同的\(a_i\)个元素,不同的集合的元素不同.将所有的元素分给\(m\)个不同位置,要求每个位置至少有一个元素,求分配方 ...
- 使用JavaScript时要注意的7个要素
每种语言都有它特别的地方,对于JavaScript来说,使用var就可以声明任意类型的变量,这门脚本语言看起来很简单,然而想要写出优雅的代码却是需要不断积累经验的.本文利列举了JavaScript初学 ...
- 你是否彻底了解margin属性?
写css,你少不了与margin打交道.你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素.内联元素中的区别?什么时候该用padding而不是m ...
- 用JavaScript写一个类似PHP print_r的函数
PHP print_r的函数很好用,可以用来打印数组.对象等的结构与数据,可惜JavaScript并没有原生提供类似的函数.不过我们可以试着自己来实现这个函数,下面提供一些方法与思路. 方法一 fun ...