一、 实践题目
设有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
二、 问题描述
要让磁带存储尽可能多的程序,如果先将程序长度较长的放进磁带,那么存储的数量则会随着程序长度变长而变少。
所以,应该将程序的长度做一个非降序的排序,先将长度少的程序存储好。
三、 算法描述
先用数组a[]将所有程序的长度存储下来,用STL库里的sort函数对数组进行非降序排序,得到长度从小到大的数组。
用for循环进行遍历,如果数组长度小于等于磁带总长L,则计数器cnt++记录次数,总长L = L – a[i],最后输出cnt则完成。
证明:三个程序长度分别为a,b,c,其中a>b>c;
(1)如果a>=b+c那么肯定是不选a,而是去选b和c。
(2)如果a<b+c,就是在长度a以内最多只能存储1个程序,那么此时选择更短的程序来使剩下的长度更多尽可能存储更多的程序。
代码实现:
#include<bits/stdc++.h>
using namespace std;
int cnt = 0;
int main(){
int n,a[1001],len;
cin>>n>>len;
for(int i = 1;i <= n; i++){
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i = 1;i <= n;i++){
if(a[i] <= len){
cnt++;
len -= a[i];
}
}
cout<<cnt;
}
四、 时间及空间复杂度
时间复杂度:用到一个for循环(O(n))进行遍历,而且运用了sort函数(O(nlogn)),所以时间复杂度为(O(nlogn))。
空间复杂度:开了一个数组a【1000】,所以空间复杂度是O(1)。
五、 心得体会
贪心策略不像动态规划那么绕,但它也有它的难点所在,比如不是所有题目都可以用贪心策略来解决的。例如第四章作业题里的货币找零,所以如何“因地制宜”调整贪心策略则成了我们需要学习的地方。
另外,我和我们变成小伙伴合作得非常愉快,希望接下来能继续向他学习,一起学好算法这门课。