贪心算法的简述与示例

贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质。

参考:http://babybandf.blog.163.com/blog/static/61993532010112923767/

[例1]删数问题[B][/B]

试题描述  键盘输入一个高精度的正整数N(不超过240位),去掉其中任意S个数字后剩下的数字按左右次序组成一个新的正整数。对给定的N和S,寻找一种删数规则使得剩下得数字组成的新数最小。

试题背景  此题出自NOI94[B][/B]

试题分析  这是一道运用贪心策略求解的典型问题。此题所需处理的数据从表面上看是一个整数。其实,大家通过对此题得深入分析便知:本题所给出的高精度正整数在具体做题时将它看作由若干个数字所组成的一串数,这是求解本题的一个重要突破。这样便建立起了贪心策略的数学描述。

每次删除一个数字,选择一个使剩下的数最小的数字作为删除对象,之所以选择这样”贪心”的操作,是因为删S个数字的全局最优解包含了删一个数字的子问题的最优解.

当S=1时,在N中删除哪一个数字能达到最小的目的?从左到右每相邻的两个数字比较:若出现左边大于右边,则删除左边的大数字.若不出现降序排列,即所有数字全部升序,则删除最右边的大数字.

当S>1,按上述操作一个一个删除,删除一个达到最小后,再从头即从串首开始,删除第2个,依次分解为S次完成.

若删除不到S个后已无左边大于右边的减序,则停止删除操作,打印剩下串的左边L-S个数字即可(相当于删除了若干个最右边的大数字,这里L为原数字N的位数).

#include<iostream>
#include<string>
using namespace std;
int main()
{
 string n;
 int s,i,x,l,m;
 while(cin>>n>>s)
 {
  i=-1,m=0,x=0;
  l=n.length();
  while(x<s&&m==0)
  {
   i++;
   if(n[i]>n[i+1])//出现递减,删除递减的首数字
   {
    n=n.erase(i,1);
    x++;// x统计删除数字的个数
    i=-1;//从头开始查递减区间
   }
   if(i==l-x-2&&x<s)

    m=1;//已经无递减区间,m=1脱离循环
  }
  cout<<n.substr(0,l-s+x);//只打印剩下的左边l-(s-x)个数字
 }
}
时间: 2024-10-06 18:55:31

贪心算法的简述与示例的相关文章

贪心算法的理解

什么是贪心算法? 贪心算法从步步最优,到达全局最优. 什么时候能够使用贪心算法? 一般来说,凡是经过数学归纳法证明可以采用贪心法的情况都应该采用它,因为它具有高效性. 通常还有另外一个方法来判断,如果一个问题具有这两大性质,那么使用贪心法来对其求解总能求 得最优解. 1.最优子结构性质 当一个问题的最优解一定包含其子问题的最优解时,称此问题具有最优子结构性质.如何理解?换句话说:最优解一定是子问题的最优解组合而成的.(这个好像是从后到前的看问题). 2.贪心选择性质 贪心选择性质时指所求问题的整

算法复习笔记(分治法、动态规划、贪心算法)

分治法 动态规划 贪心算法 分治法 分治法的基本思想是将一个规模为n的问题分解为k个规模较小的问题,这些子问题互相独立且与原问题相同(所以可以递归).递归地解这些子问题,然后将各个子问题的解合并得到原问题的解.它的一般算法设计模式如下: divide-and-conquer(P) { //|P|表示问题的规模,n0表示阈值,当规模不超过n0时,问题容易解出,不必分解 if(|P|<=n0) adhoc(P); //将P分解成子问题 divide P into smaller subinstanc

个人总结-----非贪心算法的图的m着色判断及优化问题

1.问题描述: 对于著名的图的m着色,有两个主要的问题,一个是图的m色判定问题,一个是图的m色优化问题,描述如下. 图的m色判定问题: 给定无向连通图G和m种颜色.用这些颜色为图G的各顶点着色.问是否存在着色方法,使得G中任2邻接点有不同颜色. 图的m色优化问题:给定无向连通图G,为图G的各顶点着色, 使图中任2邻接点着不同颜色,问最少需要几种颜色.所需的最少颜色的数目m称为该图的色数. 对于网上或书上的一些求解方式主要用贪心算法求解的方式,也有用回溯法的方式(一般不用,时空太大).如这位博主 

回溯算法 和 贪心算法(全排列)

一:简介 (1)回溯法 又称试探法 回溯法的基本做法是深度优先搜索,是一种组织得井井有条的.能避免不必要重复搜索的穷举式搜索算法:基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试. 适用场景:当遇到某一类问题时,它的问题可以分解,但是又不能得出明确的动态规划或是递归解法,此时可以考虑用回溯法解决此类问题.回溯法的优点在于其程序结构明确,可读性强,易于理解,而且通过对问题的分析可以大大提高运行效率.但是,对于可以得出明显的递推公式迭代求解的问题,还是不要用回溯法,因为它花费的时间

野生前端的数据结构练习(12)贪心算法

参考代码可见:https://github.com/dashnowords/blogs/tree/master/Structure/GreedyAlogrithm 一.贪心算法 贪心算法属于比较简单的算法,它总是会选择当下最优解,而不去考虑单次递归时是否会对未来造成影响,也就是说不考虑得到的解是否是全局最优.在很多实际问题中,寻找全局最优解的代价是非常大的,这时候就可以通过求次优解来解决问题,这种思想其实在软件工程中很常见,例如React中著名的DOM Diff算法中需要对比两棵DOM树,树的完

贪心算法----过河问题

问题: 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过.如果各自单独过桥的话,N人所需要的时间已知:而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间.问题是,如何设计一个方案,让这N人尽快过桥. 输入: 第一行是一个整数T(1<=T<=20)表示测试数据的组数 每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人

[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)

1 Dijkstra算法 1.1 算法基本信息 解决问题/提出背景 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径) 算法思想 贪心算法 按路径长度递增的次序,依次产生最短路径的算法 [适用范围]Dijkstra算法仅适用于[权重为正]的图模型中 时间复杂度 O(n^3) 补充说明 亦可应用于[多源最短路径](推荐:Floyd算法(动态规划,O(n^3))) Dijkstra 时间复杂度:O(n^3) 1.2 算法描述 1.2.1 求解过程(具体思路) 1.2.2 示例 1.2

POJ1017 Packets(贪心算法训练)

Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 51306          Accepted: 17391 Description A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These pro

算法导论——lec 13 贪心算法与图上算法

之前我们介绍了用动态规划的方法来解决一些最优化的问题.但对于有些最优化问题来说,用动态规划就是"高射炮打蚊子",采用一些更加简单有效的方法就可以解决.贪心算法就是其中之一.贪心算法是使所做的选择看起来是当前最佳的,期望通过所做的局部最优选择来产生一个全局最优解. 一. 活动选择问题 [问题]对几个互相竞争的活动进行调度:活动集合S = {a1, a2, ..., an},它们都要求以独占的方式使用某一公共资源(如教室),每个活动ai有一个开始时间si和结束时间fi ,且0 ≤ si &