第6章贪心算法.ppt
《第6章贪心算法.ppt》由会员分享,可在线阅读,更多相关《第6章贪心算法.ppt(34页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第六章第六章 贪心算法贪心算法 若在求解一个问题时,能根据每次所得到的局部最优解,推导出全局最若在求解一个问题时,能根据每次所得到的局部最优解,推导出全局最优或最优目标。那么,我们可以根据这个策略,每次得到局部最优解答,逐优或最优目标。那么,我们可以根据这个策略,每次得到局部最优解答,逐步而推导出问题,这种策略称为步而推导出问题,这种策略称为贪心法贪心法。下面我们看一些简单例题。下面我们看一些简单例题。【例【例1】在在N行行M列的正整数矩阵中,要求从每行中选出列的正整数矩阵中,要求从每行中选出1个数,使得选出的总共个数,使得选出的总共N个个数的和最大。数的和最大。【算法分析】【算法分析】 要使
2、总和最大,则每个数要尽可能大,自然应该选每行中最大的那个数。因此,要使总和最大,则每个数要尽可能大,自然应该选每行中最大的那个数。因此,我们设计出如下算法我们设计出如下算法:读入读入N, M,矩阵数据;矩阵数据;Total = 0;for (int l= 1; l=0) /将第i种商品全部装入卡车 else 将(m+wi) 重量的物品i装入卡车; i=i+1; /选择下一种商品while (m0&inr; memset(s,0,sizeof(s); /初始化 j=0; minx=0; for (i=1;i=n;+i) /用贪心法求解 j+; if (j=r+1) j=1; /前前r个人为一组,
3、第个人为一组,第r+1个人回到第一个水龙个人回到第一个水龙 sj+=ai; /加上等待时间加上等待时间 minx+=sj; cout从取3张牌放到 (9 11 10 10)- 从取1张牌放到(10 10 10 10)。【输入格式】 N(N 堆纸牌,1 = N = 100) A1 A2 An (N 堆纸牌,每堆纸牌初始数,l= Ai n;ave=0;step=0; for (i=1;iai; ave+=ai; /读入各堆牌张数,求总张数读入各堆牌张数,求总张数ave ave/=n; /求牌的平均张数求牌的平均张数avefor (i=1;i=n;+i) ai-=ave; /每堆牌的张数减去平均数每
4、堆牌的张数减去平均数i=1;j=n;while (ai=0&i1) -j; /过滤右边的过滤右边的0while (ij) ai+1+=ai; /将第将第i堆牌移到第堆牌移到第i+1堆中去堆中去ai=0; /第第i堆牌移走后变为堆牌移走后变为0+step; /移牌步数计数移牌步数计数 +i; /对下一堆牌进行循环操作对下一堆牌进行循环操作while (ai=0&ij) +i; /过滤移牌过程中产生的过滤移牌过程中产生的0 coutstependl; 点评:基本题,本题有点评:基本题,本题有3点比较关键:一是善于将每堆牌数减去平均数,简化了点比较关键:一是善于将每堆牌数减去平均数,简化了问题;二是
5、要过滤掉问题;二是要过滤掉0(不是所有的(不是所有的0,如,如-2,3,0,-1中的中的0是不能过滤的);三是是不能过滤的);三是负数张牌也可以移动,这是关键中的关键。负数张牌也可以移动,这是关键中的关键。【例【例5】删数问题(】删数问题(NOI94)输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序组成一个新的正整数。编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小。 输出新的正整数。(N不超过240位)输入数据均不需判错。【输入】 n s【输出】 最后剩下的最小数。【样例输入】 175438 4【样例输出】 13【算法分析】 由于正整数n的有效数位为240位
6、,所以很自然地采用字符串类型存贮n。那么如何决定哪s位被删除呢?是不是最大的s个数字呢?显然不是,大家很容易举出一些反例。为了尽可能逼近目标,我们选取的贪心策略为:每一步总是选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字;否则删除第一个递减区间的首字符,这样删一位便形成了一个新数字串。然后回到串首,按上述规则再删下一个数字。重复以上过程s次为止,剩下的数字串便是问题的解了。例如:n=175438 s=4 删数的过程如下: n=175438 /删掉7 15438 /删掉5 1438 /删掉4 138 /删掉8 13 /解为13 这样,删数问题就与如
7、何寻找递减区间首字符这样一个简单的问题对应起来。不过还要注意一个细节性的问题,就是可能会出现字符串串首有若干0的情况,甚至整个字符串都是0的情况。按以上贪心策略编制的程序框架如下 输入n,s; for (i=1;i=s;+i) /一共要删除s个字符 for ( j=0;jnj+1 ) /找到第一个符合条件的 for ( k=j;k导弹导弹i的高度的高度;lp导弹导弹i的高度的高度)(ijk)。这样可使得)。这样可使得一套系统拦截的导弹数尽可能增多。一套系统拦截的导弹数尽可能增多。依次类推,直至分析了依次类推,直至分析了n枚导弹的高度为止。此时得出的枚导弹的高度为止。此时得出的k便为应配备的最少
8、系统数。便为应配备的最少系统数。参考程序主要框架如下:参考程序主要框架如下:k=1;lk=导弹导弹1的高度的高度; for (i=2;i=n;+i) p=0;for (j=1;j=导弹导弹i的高度的高度) if (p=0) p=j; else if (ljlp) p=j; /贪心贪心 if (p=0) +k;lk=导弹导弹i的高度的高度; /增加一套新系统增加一套新系统 else lp=导弹导弹i的高度的高度; /贪心贪心,更新第更新第p套系统的最低高度套系统的最低高度 输出应配备的最少系统数输出应配备的最少系统数K。 【例7】活动选择 学校在最近几天有n个活动,这些活动都需要使用学校的大礼堂
9、,在同一时间,礼堂只能被一个活动使。由于有些活动时间上有冲突,学校办公室人员只好让一些活动放弃使用礼堂而使用其他教室。 现在给出n个活动使用礼堂的起始时间begini和结束时间endi(begini endi),请你帮助办公室人员安排一些活动来使用礼堂,要求安排的活动尽量多。 【输入】 第一行一个整数n(n=1000); 接下来的n行,每行两个整数,第一个begini,第二个是endi(begini endi =32767)【输出】 输出最多能安排的活动个数。【样例输入】113 51 412 148 120 68 116 105 73 85 92 13【样例输出】 4 【算法分析】 算法模型:
10、给n个开区间(begini,endi), 选择尽量多的区间, 使得两两不交。 做法: 首先按照end1=end2=endn的顺序排序,依次考虑各个活动, 如果没有和已经选择的活动冲突, 就选; 否则就不选。 正确性: 如果不选end1, 假设第一个选择的是endi,则如果endi和end1不交叉则多选一个end1更划算; 如果交叉则把endi换成end1不影响后续选择。 【参考程序】#includeusing namespace std;int n,begin1001,end1001;void init() cinn; for(int i=1;ibeginiendi;void qsort(in
11、t x,int y) int i,j,mid,t; i=x;j=y;mid=end(x+y)/2; while(i=j) while(endimid) -j; if(i=j) t=endj;endj=endi;endi=t; t=beginj;beginj=begini;begini=t; +i;j; if(xj) qsort(x,j); if(iy) qsort(i,y); void solve() int ans=0; for(int i=1,t=-1;i=t) +ans;t=endi;/如果当前活动与之前最后结束的活动不冲突, 就接受当前活动。 coutansendl;int main(
12、) init(); qsort(1,n); solve(); return 0; 【例8】整数区间 请编程完成以下任务: 1.从文件中读取闭区间的个数及它们的描述; 2.找到一个含元素个数最少的集合,使得对于每一个区间,都至少有一个整数属于该集合,输出该集合的元素个数。 【输入】 首行包括区间的数目n,1=n=10000,接下来的n行,每行包括两个整数a,b,被一空格隔开,0=a=b=10000,它们是某一个区间的开始值和结束值。【输出】 第一行集合元素的个数,对于每一个区间都至少有一个整数属于该区间,且集合所包含元素数目最少。【样例输入】 43 62 40 24 7【样例输出】2 【算法分析
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 贪心 算法
限制150内