贪心算法

【算法导论】贪心算法,递归算法,动态规划算法总结

主宰稳场 提交于 2020-02-23 10:26:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖

【算法导论】贪心算法,递归算法,动态规划算法总结

痴心易碎 提交于 2020-02-23 10:24:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖

贪心 & 并查集压缩路径 -- Supermarket POJ - 1456

寵の児 提交于 2020-02-21 11:36:24
Supermarket POJ - 1456 题意: 是买卖N件东西,每件东西都有个截止时间,在截止时间之前买都可以,而每个单位时间只能买一件。问最大获利。 思路: 用贪心做,用并查集来加快速度,太精妙了。 如果购买不冲突,那么全部买下来就可以了。存在冲突,就需要取舍。显然在冲突的时候我们选择价格高的更优,如此就可以用贪心的算法。先将物品按照价格从高到底的顺序排列,购买一个就在时间点上做一个标记,只要不冲突就可以购买。 如何快速找到第一个不冲突的时间点呢,使用并查集很好得解决了这个问题。 这里并查集的作用类似于链表指针,压缩的过程就是删掉节点的过程。从而在O(1)的时间内找到那个不冲突的点。 code: # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> using namespace std ; const int maxn = 10010 ; int F [ maxn ] ; truct Node { int p , d ; } node [ MAXN ] ; bool cmp ( Node a , Node b ) { return a . p > b . p ; } int find ( int x ) { if ( F [ x ] == - 1 )

HDOJ题目分类

你。 提交于 2020-02-21 07:22:40
1001 整数求和 水题 1002 C语言实验题——两个数比较 水题 1003 1、2、3、4、5... 简单题 1004 渊子赛马 排序+贪心的方法归并 1005 Hero In Maze 广度搜索 1006 Redraiment猜想 数论:容斥定理 1007 童年生活二三事 递推题 1008 University 简单hash 1009 目标柏林 简单模拟题 1010 Rails 模拟题(堆栈) 1011 Box of Bricks 简单题 1012 IMMEDIATE DECODABILITY Huffman编码 1013 STAMPS 搜索or动态规划 1014 Border 模拟题 1015 Simple Arithmetics 高精度计算 1016 Shoot-out 博弈+状态压缩DP 1017 Tour Guide 1018 Card Trick 简单题 1019 Necklace Decomposition 贪心 1020 Crashing Robots 模拟题 1021 Electrical Outlets 简单题 1022 Watchdog 简单题 1023 Taxi Cab Scheme 图论:最小路径覆盖--->最大二分匹配 1024 Pseudo-random Numbers 数论 1025 Card Game Cheater 简单题 1026

LeetCode 135 Candy(贪心算法)

安稳与你 提交于 2020-02-19 04:04:59
135. Candy There are N children standing in a line. Each child is assigned a rating value. You are giving candies to these children subjected to the following requirements: Each child must have at least one candy. Children with a higher rating get more candies than their neighbors. What is the minimum candies you must give? 要求使用最少的糖分给不同孩子,要注意只是有更高分数的拿更多的糖,相同分数可以给不同数量的糖。 考虑对第 i 个孩子,如果他的分数等于之前的孩子,那给他一颗糖就能满足条件。如果他的分数大于之前的孩子,给他前一个孩子的糖+1。如果小于,考虑给一颗糖,如果上一个孩子有不止一颗糖,可以满足条件,但是如果上一个孩子只有一颗糖,对上一个孩子来说,他有比右边孩子更高的分数,但是只有相同的糖的数目。所以这种情况需要重新考虑。 一个方法是对 i 之前的孩子遍历,依次增多糖的数目直到满足条件,但是这样复杂度达到O(n^2),后面的case会超时。所以只能改变思路

集训2:贪心

て烟熏妆下的殇ゞ 提交于 2020-02-17 23:06:08
贪心算法是指在对问题求解时,总是做出在当前看来是最优的决策 换言之,就是不从全局最优方面考虑,只考虑局部最优情况 贪心算法有时可以得到全局的最优解,这取决于贪心的策略 1.排队接水问题: 有N个小朋友来接水,每个人接水要用ai的时间,求最小的等待总时间。等待总时间是指所有小朋友的等待时间之和 显然这是一个小学奥数中的简单题.. 我们让接水时间短的人排在前面,时间长的人排在后面,可以证明这种方案是正确的 #include<iostream> #include<cstdio> #include<algorithm> #include<iomanip> using namespace std; struct people{ int t; int x; }a[1001]; bool cmp(people t1,people t2) { return t1.t<t2.t; } int main() { int n; double sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].t; a[i].x=i; } sort(a+1,a+n+1,cmp); for(int j=1;j<=n;j++) { cout<<a[j].x<<" "; if(n-j>=1)sum+=a[j].t*(n-j); } cout<<endl; printf("%.2lf

B计划 第四周(开学第一周)

北城以北 提交于 2020-02-17 19:20:13
又是一周出始,init(),我自己都不知道下周我还有没有机会在继续写第五周。开学了,本周30题。 1、韩梅梅的抽象画。dfs 2、卡牌游戏。博弈论。 3、分蛋糕。遍历 4、学生排队。写个双向链表。 5、地铁修建。分支限界算法,优先队列。 6、Arpa and a research in Mexican wave. 分段函数 7、Arpa and an exam about geometry. 几何旋转。 8、Letters Deque. 双端队列。 9、Flip the Matirx. 矩阵旋转。 10、Set subtraction. 11、Tire树。板子题。 12、keywords search 多模式串匹配。 13、long long string. 最长公共子串的长度。后缀数组的前缀数组就是子串。 14、glass beads 最小表示法 15、remove update 。区间加值,维附最大值。刚开始pushDown时忘了更新区间最值。 16、黑白图像直方图 17、大数乘法。FFT 18、瞬间移动。打表找规律(或者脑力分析),组合数取模。 19、Planning. 贪心题,维护堆。 20、非常完美。筛 21、石子合并。贪心(堆,排序) 22、中间数。二分 23、引水入城。网络流求最大流 24、工资计算。把分段函数逆过来。 25、最大波动。暴力求解。 26

[LeetCode] Jump Game II 贪心

落花浮王杯 提交于 2020-02-13 23:58:04
Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps. For example: Given array A = [2,3,1,1,4] The minimum number of jumps to reach the last index is 2 . (Jump 1 step from index 0 to 1, then 3 steps to the last index.) Hide Tags Array Greedy 这题是前面一题的变种,其实用的是贪心算法,不过数据设置了时间限制,所以需要提交效率,最好就是一次O(n)时间。 为了提高时间需要做一个思考,如下面位置,是否存在 i-th 需要跳的 最少 次数少于i-1 th 位置,如 ... i-1 i ... 3 2   这个可以这么思考,如果i 是从i-1 跳到的

贪心算法-跳跃游戏二

倖福魔咒の 提交于 2020-02-13 22:39:27
给定一个非负整数数组,假定你的初始位置为数组第一个下标。 数组中的每个元素代表你在那个位置能够跳跃的最大长度。 你的目标是到达最后一个下标,并且使用最少的跳跃次数。 例如: A = [ 2 , 3 , 1 , 1 , 4 ],到达最后一个下标的最少跳跃次数为 2。(先跳跃 1 步,从下标 0 到 1,然后跳跃 3 步, 到达最后一个下标。一共两次) 输入格式 第一行输入一个正整数 n ( 1 ≤ n ≤ 1 0 0 ) ,接下来的一行,输入 n 个整数,表示数组 A。 输出格式 最后输出最少的跳跃次数。 样例输入 5 3 1 1 1 1 样例输出 2 分析: 通过上面例题分析,类似于贪心算法,每次跳一步后,步数cnt++,然后判断下次跳的最远的距离,直到到达s[n-1]为止,如下图所示: 代码如下: #include<stdio.h> int n,s[10000]={0},ct=0; int bfs(int i) { int k,j=0,l,max=0; if(i>=n-1) return 0; //找到便退出 k=s[i];ct++; if(i+k>=n-1) return 0; //找到便退出 for(l=i+1;l<=i+k;l++) //for()找到下次能跳到最远的距离 { if(max<=l+s[l]) //更新数据 { j=l;max=l+s[l]; } } bfs

贪心算法-跳跃游戏——b

Deadly 提交于 2020-02-13 22:39:02
1、题目描述 定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 2、问题分析   这也是一道跳跃问题,但是这道题的目的是让我们计算跳到最后一个位置的最小跳跃次数。我们一直的是这个数组一定能从第一个位置跳到最后一个位置,但是不同的跳跃情况跳跃的次数是不一样的,怎样能保证跳跃的次数是最少的呢?跳的次数最少其实就是保证尽可能少的跳跃次数也能最后达到数组最后一个位置。 输入: [2,3,1,1,4] 输出: 2 解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。 3、算法思路 回想第一个跳跃问题情景,我们是保证在遍历整个数组的过程中记录下经过的index[]中能跳到最远位置的值max_index,在jump往后遍历的过程中,只要保证jump的值一直小于或者等于max_index的值,其实就相当于是我们能一直往后跳跃,最后比较jump是不是能跳到index[]数组的最后一个位置。但这里我们稍微转变一下思路就好了:贪心思想(能不跳就尽量不跳,不跳就一直往下走)要想尽可能少的跳跃到最后一个位置,那么我们就保证能不跳跃就不跳跃,实在是往下没办法往下走的情况下就跳跃一次。但这一次跳跃是跳到哪里呢