算法第四章上机实验报告

4-1 程序存储问题
有限空间中放最多的程序,很容易就可以想到优先放最小的程序,就会得到最大数量。

    sort(a, a + n);
    //sum为存储空间大小
    for(int i = 0; i < n; i++) {
        sum -= a[i];
        if(sum < 0) {
            cout << i;
            break;
        }
        if(sum == 0) {
            cout << i + 1;
            break;
        }
    }

  时间复杂度为 O(n * log n)


4-2 删数问题

给定一串数字,题目要求删掉 t 个数字(删掉后先后关系不变),问如何删才能取得最小值。

可以从另一个问题引申出求解思路

问题:假设有 x 个数字可以任意排列,如何才能让其取值最小?
答案:小的数放在高位,大的数放在低位,使他由高位到低位单调递增

此题原理相同,要使得得到的数最小,就每次删掉逆序的数就可以了。

    while(t--) {  //t为要删除数字的个数
        int cnt = 0;//记录要删掉的数的下标
        for(int i = 1; i < a.size(); i++) {
            if(a[i] < a[i-1]) {
                cnt = i - 1;
                break;
            }
        }
        a.erase(cnt, 1); //删除选中数
        if(a.size()==0) {
            cout << 0;
            return 0;
        }
	//删掉前导0
        while(a.size() > 1 && a[0]=='0') {
            a.erase(0, 1);
        }
    }
	//因为直接以字符串读取一行会多出一个空格,所以先判断一下是不是数字
    for(int i = 0; i < a.size(); i++) if(isdigit(a[i])) cout << a[i];

  假设有 n 位数字,时间复杂度为 O(t * n)


 4 - 3 最优和并问题

用到哈夫曼树,用大根堆,小根堆能快速解决,优先最大的或最小的两个,没什么难点。

  时间复杂度,优先队列插入单个数是 log n 的,n 个数,所以是 O(n * log n) 的。 


 总结:贪心算法没有固定的套路,有时候证明也很难,但比较符合人的直觉,很多时候可以先猜想再通过程序去验证。

posted @ 2021-11-13 00:22  有手也不行  阅读(17)  评论(0编辑  收藏  举报