挑战程序设计竞赛笔记-贪心算法
2.2 贪心算法
贪心算法的精髓在于,遵循某种规则,不断地选取当前最优解。
硬币问题
假设有 1 元,5元,10元,50元,100元,500元的硬币C1,C5,C10,C50,C500枚,现在需要凑出 A 元
问如何组合才能使硬币的数量最少?
这道题给人的印象就是,为了使得硬币数目最少,尽可能使用面值大的硬币。这种策略就是计算过程中的规则。尽可能使用最大面值,就是当前最优解。
所以,使用每个硬币的数目为:
int t = min(A/Y ,Y_Max); //A为目标,Y为面值,Y_Max为面值为Y的硬币数目。
下面练习一道POJ3617:
2.2.1.BestCowLine
给定长度为N的字符串S,要构造一个长度为N的字符串T,最开始T是一个空串,随后反复进行如下操作:1.从S的头部删除一个字符,加到T的尾部2.从S的尾部删除一个字符,加到T的头部目标是构建一个字典序尽可能小的字符串T。
这道题的贪心策略就是,每次都选取字符串S两头字典序较小的那个。因为规定只能从两端取,所以若两端的字典序有差别,则可以直接根据当前情况选择当前最优解。我们的需求也是,每次要选择小字典序的字母插入队列。
但是,如果字典序一样该选哪个呢?对于相同的字典序,对于当前情况是没有区别的。可是,如果一个字典序是ZB…CZ,那么如果选择右侧的先,则会导致接下来选择的是ZC…而先选左边,则会产生ZB,这样明显选左边产生的字典序更小。所以,对于相同的两端,我们应该持续比较下一个字符。如果下一个字符也是相同的,则要循环下去。
我其实还思考了蛮久了,为什么要一直循环下去。后来总结道:
| |
| | | |
| | | | | |
| | | _ ..... | | | |
如果以竖线高低作为字典序高低,只有这种排列的顺序,按照上面循环匹配才有效。
即 “相等项后面字典序递减”
如上图,选取左侧的字典序是 4-3-2-0 ,而选右边则是4-3-2-1,字典序右边高。(让我们忽略省略号,只考虑接下来四个字母)
#include<stdio.h>int n;//length
char str[2001];
//char ans[2000];void create(char* str){int i = 0;int a = n-1;int count = 0;bool left=false;//默认推右边while(i<=a){for(int j=0;i+j<=a-j;j++){//如果字典序相同if(str[i+j]<str[a-j]){left = true;break;}else if(str[i+j]>str[a-j]){left = false;break;}}if(left){putchar(str[i++]);}else{putchar(str[a--]);}}putchar('\n');
}int main(){while(scanf("%d",&n)!=EOF){for(int i=0;i<n;i++){scanf(" %c\n", & str[i]);}str[n]='\0';create(str);}}
2.2.2 Saruman’s Army
poj 3069
在一条直线上,有n个点。从这n个点中选择若干个,给他们加上标记。
对于每一个点,其距离为R以内的区域里必须有一个被标记的点。问至少要有多少点被加上标记。
这道题的贪心策略是,从左到右看这些点。遇到第一个点,以它为圆心画一个半径为R的圆,右侧离圆最近的点作为第一个标记点。为什么不选第一个点作为标记点呢?如果把这个作为萨鲁曼(魔戒梗)的施法范围,第一个人作为标记点,其左侧并没有覆盖任何点。这样就会造成浪费。
第二次,我们就选取上一次标记点的下一个点,作为半径圆心,再按照第一次寻找那样选取点。
直到圆的右侧没有点的时候,程序退出。
这道题感觉还挺简单的,并没有去做它。
2.2.3 Fence Repair
poj 3253
有一个农夫要把一个木板钜成N块给定长度的小木板,每一次费用就是当前锯的这个木板的长度 给定小木板的个数n,各个要求的小木板的长度。求最小费用
如:要5,5,8的木板,需要先将总长度18锯成10,8 再锯成5,5 。最小花费为28.
这道题和搬运水果一样,相当于搬运水果的时空倒流。也就是,我们将两块木板合到一起,花费的代价是这两块木板长度的和。现在要把他们合成一块,需要最少多少的代价。
我们知道,每次合并能减少一块,所以一定需要N-1次合并才能合成一块。但是我们如何选取呢?
根据哈夫曼树,我们应该尽可能使得代价小的木板在叶节点。相当于重复将他们多次合并。处于越深的叶节点,相当于合并这块木板的次数最多。而使得次数多的代价小,能达到最优解。
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;int main(){int n;priority_queue<int,vector<int>,greater<int> > c;int s;while(scanf("%d",&n)!=EOF){long long ans=0;while(!c.empty())c.pop();for(int i=0;i<n;i++){scanf("%d",&s);c.push(s);}int a,b;if(c.size()==1){ans = c.top();break;}while(!c.empty()){a = c.top();c.pop();b = c.top();c.pop();ans += a+b;c.push(a+b); if(c.size()==1)break;}printf("%lld\n",ans);
}
}
上面的代码使用了优先队列
priority_queue<int >a
这样定义默认是大顶堆结构,即先出队列的是大的值。
priority_queue<int ,vector<int>,greater<int> > a
定义了一个小顶堆队列。
这一数据结构在 #queue 头文件里。
挑战程序设计竞赛笔记-贪心算法相关推荐
- 【操作指导 | 代码实现】挑战程序设计竞赛2:算法和数据结构
书籍封面 第一章 前言 1. 本人衷心建议 ~~~~~~ 如果你是一位初学者,我指的是你只会基本的 C/C++ 编程,即使编的很烂,这本书对于你算法和数据结构的提升非常有帮助,所涉及的每一 ...
- 《挑战程序设计竞赛》--初级篇习题POJ部分【穷竭搜索+贪心】
最近看了<挑战程序设计竞赛>初级篇,这里总结一下部分poj上的练习题,主要涉及方面为: 穷竭搜索 and 贪心算法 具体题目: 简单导航 一.穷竭搜索 二.贪心算法 一.穷竭搜索 穷竭搜索 ...
- 《挑战程序设计竞赛》阅读笔记二 之 ALDS1_2_C Stable Sort
<挑战程序设计竞赛>阅读笔记二 之 ALDS1_2_C Stable Sort 第三章 Sort I ALDS1_2_C Stable Sort 这道题目,就是为了说明 冒泡排序是稳定排序 ...
- 《挑战程序设计竞赛》推荐及算法相关书籍吐槽
前几天,秋叶拓哉(iwi).岩田阳一(wata)和北川宜稔(kita_masa)所著,我(watashi).庄俊元(navi)和李津羽(itsuhane)翻译的<挑战程序设计竞赛>,终于通 ...
- koch算法c语言递归,【挑战程序设计竞赛】 递归与分治算法
[挑战程序设计竞赛] 递归与分治算法 [挑战程序设计竞赛] 递归与分治算法 递归与分治算法穷举搜索题目 思路 代码 科赫曲线题目 思路 代码 将问题分解,通过求解局部性的小问题来解决原本的问题,这种技 ...
- 《挑战程序设计竞赛(第2版)》习题册攻略
本项目来源于GitHub 链接: 项目GitHub链接 1 前言 项目为<挑战程序设计竞赛(第2版)>习题册攻略,已完结.可配合书籍或笔记,系统学习算法. 题量:约200道,代码注释内含详 ...
- 挑战程序设计竞赛(第2版)》
<挑战程序设计竞赛(第2版)> 基本信息 作者: (日)秋叶拓哉 岩田阳一 北川宜稔 译者: 巫泽俊 庄俊元 李津羽 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787 ...
- ICPC程序设计题解书籍系列之三:秋田拓哉:《挑战程序设计竞赛》(第2版)
白书<挑战程序设计竞赛>(第2版)题目一览 白书:秋田拓哉:<挑战程序设计竞赛>(第2版) 第1章 蓄势待发--准备篇(例题) POJ1852 UVa10714 ZOJ2376 ...
- 《挑战程序设计竞赛》 读后感(转载)
<挑战程序设计竞赛> 读后感 最近要开始准备面试找工作,算法是准备的重中之重,舍友推荐了<挑战程序设计竞赛>这本书.花了一周的时间大体过了一遍,该书真切地让我理解了" ...
最新文章
- 数据结构实验之链表二:逆序建立链表
- zbb20170824 oracle expdp/impdp 导入导出数据
- 不同编程语言在发生stackoverflow之前支持的调用栈最大嵌套层数
- 如何遍历一个JS对象中的所有属性,输出键值对--我居然犯错半个小时
- ARM中LDR伪指令与LDR加载指令
- java 判断 框架类型_第10章-验证框架 --- 验证器类型
- linux 简单命令
- 二叉查找树--插入、删除、查找
- iOS延时执行的几种方法
- 像素测量工具_PicPick v5.0.6 屏幕截图工具
- ubuntu 16.04 系统安装保留原home分区
- Wincc 7.5 SP1使用VBS创建Excel日报表并显示在画面
- 机器人自带触觉反馈,隔空微创手术的利器
- easy connect显示‘网络请求异常请稍后重试’
- 腾讯云直播相关问题处理
- 笔记本电脑也是一种微型计算机,计算机一级试题 很权威的哦
- DM数据库windwos和linux环境单机安装部署
- Vue移动网页开发调试过程(第二篇)——weinre
- 《计算机网络技术》第一章测试(题目及答案)
- Python打包源码
热门文章
- Ubuntu 11.10 Linux 3D桌面完全教程,显卡驱动安装方法,compiz特效介绍,常见问题解答
- linux怎样通过手机上网,Linux系统通过手机GPRS上网的设置教程
- 腾讯终面:孤单的QQ号码怎么找?
- 「人物特写」清华大学教授、IEEE Fellow王志华:几乎所有的AI,到现在为止都是胡扯...
- 我国网民规模近10亿:4成初中学历 近3成月收入超5000元
- 清华大学计算机系高考生源,清华在京录取圆满结束:生源好、质量优、扩幅大(转贴)...
- 【BZOJ3811】玛里苟斯(线性基)
- Shell- 获取ESXI主机虚拟交换机中MAC表
- 上市 | 章泽天 : 刘强东用10秒钟时间决定投资这个汽车
- p4est 2.3.2 安装