实践题目 4-2 删数问题 (110 分) 给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。 输入格式: 第 1 行是1 个正整数 a。第 2 行是正整数k。 输出格式: 输出最小数。 输入样例: 在这里给出一组输入。例如: 178543 4 输出样例: 在这里给出相应的输出。例如: 13 问题描述 给你一个数字,让你删除k个数字,输出最小数(要删除前导0)。 算法描述 正解:从左边开始删除大于右边的每一个数字。如1651删除6变成151,删除5变成11. 从高位开始,删除数字比右边大的数显然正确。 本人想法:定义函数gao(l,r,num)表示在区间【l,r】中删除num个数得到的最小数 找出区间中的最小值,其下标为xb,定义n为最小值左边数的个数(不包括最小值) 如果 n <= num,说明要把最小值左边的数全部删了,因为左边的数都比最小值大,高位的数要尽可能小。 如果 n > num,说明要把左边的数全删,同时计算最小值右边的最小数(注意更新删除数字的个数)。 删除左边数的理由是高位数要尽可能小,所以把最小值放在最高位显然合理,根据此贪心策略继续计算右边区间部分。 算法时间复杂度和空间复杂度分析 正解:每删除一个数字要从头遍历,同时移动数组,所以时间复杂度是O(n^2+k),没有用到额外数组,所以空间复杂度是O(1)。 本人算法:找最小值要O(n),最坏情况递归n次,所以时间复杂度是O(n^2+k),因为用了递归,所以空间复杂度是O(n)。 正解代码:(百度的) View Code 本人代码:(没有优化找最小值) View Code 心得体会 这次实践debug时间有点久,最后发现(数字1)写成了(字母L)(╯‵□′)╯︵┻━┻ ,可能是因为一开始想错了,改思路的时候脑子有点乱,同时代码也有 -1 和 -l 的操作,一不小心就打错了。吸取教训,以后多写几个变量定义x-1和x-l,不要一边想整体一边想细节。
实践题目:程序存储问题
问题描述
设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是 li,1≤i≤n。 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序。 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数。
输入格式:
第一行是2 个正整数,分别表示文件个数n和磁带的长度L。接下来的1行中,有n个正整数,表示程序存放在磁带上的长度。
输出格式:
输出最多可以存储的程序数。
输入样例:
在这里给出一组输入。例如:
6 50
2 3 13 8 80 20
输出样例:
在这里给出相应的输出。例如:
5
算法描述
先对程序进行从小到大排序,然后依次放入磁带直到放不下。
证明:假设最优解有{p2,p4},而p1 < p2,那么把p2换成p1组成的解{p1,p4},放入的程序数不变而且也满足题意,所以{p1,p4}也是一组最优解,贪心策略正确。
算法时间及空间复杂度分析
时间复杂度:排序O(nlogn),判断程序能否放入磁带O(n),所以时间复杂度为O(nlogn)
空间复杂度:开了一个变量记录已放程序的总空间,空间复杂度为O(1)。
心得体会
这次实践debug时间有点久,最后发现(数字1)写成了(字母L)(╯‵□′)╯︵┻━┻ ,可能是因为一开始想错了,改思路的时候脑子有点乱,同时代码也有 -1 和 -l 的操作,一不小心就打错了。吸取教训,以后多写几个变量定义x-1和x-l,不要一边想整体一边想细节。