Blog 12 | 算法·实验报告3(第四章-贪心)

算法·实验报告3

主题:贪心

时间:2019/11/16

 

分析程序存储问题。内容包括:

1、实践题目

 

 

2、问题描述

设E = { l1,l2,l3,l4,l5,l6 },即初始化(程序长度按非递减排序)待选程序长度,设A = {  },即已经选中程序长度。

第i次选择中,E={ li+1,li+2 .... },A = { .... li-1,li },即每次选择当前待选程序中长度最小的程序,直到已选择的长度总和大于L。

 

3、算法描述

(1)贪心策略:每次选择长度最短的程序,不断产生的新待使用磁带长度(子问题)。

(2)代码

#include <iostream>
#include <algorithm>
using namespace std;

int length[1000];

int answer(int n,int l){
    sort(length,length+n);
    int r = l;
    int count = 0;
    for(int i = 0; i < n ;i++){
        if(length[i]<=r){
            count++;
            r = r-length[i];            
        }
        else
            break;
    }
    return count;
}

int main(){
    int n,l;
    cin>>n>>l;
    for(int i = 0 ;i < n ; i++){
        cin>>length[i];
    }
    cout<<answer(n,l);
}

 

(3)证明过程

-1的子问题,这个n-1的子问题也是最优的。

btw/考察一个问题的最优解,证明可修改该最优解,使得其从贪心选择开始,然后用数学归纳法证明每一步都可以通过贪心选择得到最优解
1,假定首选元素不是贪心选择所要的元素,证明将首元素替换成贪心选择所需元素,依然得到最优解;
2,数学归纳法证明每一步均可通过贪心选择得到最优解

 

(4)具体证明

贪心选择性质:

证明:假设A = { l1.... } 是问题的最优解,若问题存在一个最优解的第一个选择 是 lk(k>1),B是最优解集合,设B = A - { k } ∪ { l1 } 。

由于A,B中程序个数相同,l1<A - { k } ,所以B中的程序也是相容的,因此A,B都是最优解,也就是说B是以贪心选择程序l1开始的。

由此可见,该问题总存在以贪心选择开始的最优解。

 

最优子结构性质:设选择 A`=A - { l1 }(选择程序1后的待选集合),即证明 A` 是 E`= E-{ l1 } 的最优解。

证明:

假设A`不是E`的最优解,那么A`加上 { l1 }  后比A更多程序数目,和假设A是最优解矛盾,得证。

 

4、算法时间及空间复杂度分析

(1)时间复杂度:由于运用到一次快排nlogn,其他语句粗略计算为n,因此时间复杂度为O(nlogn)。

(2)空间复杂度:开了数组,因此空间复杂度为O(1)。

 

5、心得体会(对本次实践收获及疑惑进行总结)

本次实践在该题花的时间较少,在第二题由于各种算法思路以外的错误( if判断的边界 / 输入位数过长不能由int接收 / 字符串转数组 )导致一直卡壳,

并且在证明贪心策略时,仍是一知半解的状态,说明编程、数学功底不扎实,引以告诫编程要加量,数学要不断学习。

同时,贪心和动态、分治的区别有了更深的体会,贪心并不需要考虑“以后”,只需要考虑当前/过去,自顶向下。

 

 

参考博客:

https://blog.csdn.net/sn_zzy/article/details/16892031

https://blog.csdn.net/fan2273/article/details/73549016

posted @ 2019-11-17 15:15  丸zq  阅读(152)  评论(0编辑  收藏  举报