【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的多线程处理的实现.而 ...
随机推荐
- CentOS6.8单独编译安装PHP gd库扩展
# PHP-GD安装 #在安装之前可以先更新一下yum源,可以使用国内的阿里云源 yum -y install libjpeg-turbo-devel yum -y install freetype- ...
- Packet filtering with Linux & NAT
http://www.linuxfocus.org/ChineseGB/May2003/article289.shtml Gateway, Proxy-Arp 和 Ethernet Bridge ? ...
- online community
online community spectrum https://spectrum.chat/xgqfrms https://community.xgqfrms.xyz/ https://spect ...
- [剑指Offer] 18.二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5 [思路1 ...
- Java IO 之 File 的创建、重命名与遍历
File表示存储设备上的一个文件或目录,使用方式查看API即可,比较简单 package org.zln.io.file; import java.io.File; /** * Created by ...
- filebeat + logstash + elasticsearch + granfa
filebeat + logstash + elasticsearch + granfa https://www.cnblogs.com/wenchengxiaopenyou/p/9034213.ht ...
- mac --snip 滚动截屏
1.snip 下载配置:https://jingyan.baidu.com/article/fec4bce2458d03f2618d8b8e.html 2.mac的火狐浏览器好像不支持,必须在sofa ...
- JavaScript实现键盘操作页面跳转
对于使用笔记本的同学来说,鼠标操作比较费劲,键盘操作比较方便,下面是一段JavaScript写的,用键盘来实现页面跳转.把location后面的改成你要跳转的地址即可,示例是用方向键实现日志页面的前一 ...
- bootstrap table表格属性、列属性、事件、方法
留存一份,原文地址http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/ 表格参数 表格的参数定义在 jQuery.fn.bootst ...
- WCF分布式开发步步为赢(14):WCF安全编程--基本概念
WCF安全机制是个非常复杂的问题,因为涉及的知识点较多,所以今天这个文章,会分析进行WCF安全开发应该了解的哪些知识点.如何查看资料.为了更好地理解WCF安全相关知识,我把WCF安全机制主要知识点整理 ...