ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

贪心法简介

2019-03-31 21:39:57  阅读:225  来源: 互联网

标签:标号 ... int 简介 mSwap 集装箱 最优 贪心


1.贪心法的设计思想

例:n项活动,每项活动有开始时间和结束时间,不能同时举行,设计安排使得被安排的活动数量最多

策略:将活动结束时间从小到大排列,从前向后选择,只要与前面的活动相容,就将活动选入A

#include <iostream>
using namespace std;
int s[100], e[100], d[100];
void mSwap(int &a, int &b){
    int temp = a;
    a = b;
    b = temp;
}
void myQuickSort(int a, int b){
    if (a >= b)
        return;
    int t = a;
    int i = a + 1, j = b - 1;
    while (1){
        while (e[i] < e[t]) ++i;    //从左向右,找到第一个大于等于e[t] 
        while (e[j] > e[t]) --j;    //从右向左,找到第一个小于等于e[t] 
        if (i >= j) break;
        mSwap(s[i], s[j]);
        mSwap(e[i], e[j]);
        mSwap(d[i], d[j]);
    }
    mSwap(s[t], s[j]);
    mSwap(e[t], e[j]);
    mSwap(d[t], d[j]);
    myQuickSort(a, j);
    myQuickSort(j + 1, b);
}
int main(){
    int n;
    int count = 1;
    int pree;    //用于记录前一个活动结束时间 
    cin >> n;
    for (int i = 0; i < n; ++i){
        cin >> s[i] >> e[i];
        d[i] = i;
    }
    myQuickSort(0, n);
    pree = e[0];
    cout << d[0];
    for (int i = 1; i < n; ++i){
        if (s[i] >= pree){
            pree = e[i];
            cout << ' ' << d[i];
            count++;
        }
    }
    cout << endl << count << endl;
    return 0;
} 

2.贪心法正确性证明

有集装箱1,2,...,n准备装上轮船,其中集装箱i的重量为wi,i=1,2,...,n.已知轮船最多装载量为C,每个集装箱重量wi≤C,且对集装箱无体积限制.问如何选择而使得装上船的集装箱数量最多?

(0-1背包问题,贪心法比动态规划更简便)

【关于最终输出的集装箱标号,理应按原始标号输出,但书中是按照排序后的标号输出。敲代码时,就重写一下快排,按原始标号输出。笔试时,就直接不加说明按照排序后标号输出】

算法1:

输入:集装箱集合N={1,2,...,n},集装箱i的重量W={wi|i=1,2,...,n}

输出:I⊆N,装入船的集装箱集合

1.sort(W)

2.I={1}

3.K=w1

4.for i 2 to n do

5.  if K+wi≤C

6.  then I<-I∪{i}

7.    K<-K+wi

8.  else return I,K

【伪代码的书写规范有点迷,if...then...似乎不需要接end if,while、for后似乎也不需要接end?】

证明①:(数学归纳法)

  对于任何正整数k,算法1都对k个集装箱的实例取得最优解

  k=1时,w1≤C,任何算法仅有一种装法,显然最优解成立

  假设算法对于规模为k的输入都能得到最优解,考虑规模为k+1的输入W[1..k+1],排序后有W[1]≤...≤W[k+1],去掉最轻的集装箱

    N'=N-{1}

    W'=W-{w1}

    C'=C-w1

  根据归纳假设,对于N',W',C',算法1能得到最优解I'

  令I=I'∪{1}

  则I是N的最优解,如若不然,则存在关于N的最优解I*,I*包含1(否则用1替换标号最小的集装箱,也是最优解),|I*|>|I|

    |I*-{1}|>|I-{1}|=|I'|

  与I'是N'的最优解矛盾

  故该算法对规模为k+1的输入也能得到最优解

  综上,命题得证

证明②:(交换论证)

思路:通过有限步替换,将任意最优解改变成贪心法的解

  假设f=<i1,i2,...,in>是一个最优解,如果在f中存在逆序,即存在wj<wk,而f(j)>f(k)

  交换f中j与k,得到调度g,下证明g为最优解:

    K=w1+w2+...+wi

  i<j时,Kf=Kg

  j≤i<k时,∵wj<wk∴Kf=C1+wk+C2≥C1+wj+C2=Kg

  i≥k时,Kf=Kg

  故若f为最优解,则g为最优解

由代数定理得,经过有限次置换,可得到不存在逆序的最优解,即为算法1得到的解

标签:标号,...,int,简介,mSwap,集装箱,最优,贪心
来源: https://www.cnblogs.com/victorique-de-blois/p/10633316.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有