434
社区成员
发帖
与我相关
我的任务
分享设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是 li,1≤i≤n。 程序存储问题要求确定这n 个程序在磁带上的一个存储方案, 使得能够在磁带上存储尽可能多的程序。 对于给定的n个程序存放在磁带上的长度,计算磁带上最多可以存储的程序数。
输入格式:
第一行是2 个正整数,分别表示文件个数n和磁带的长度L。接下来的1行中,有n个正整数,表示程序存放在磁带上的长度。
输出格式:
输出最多可以存储的程序数。
解法:由题意可得程序需要在磁带上存放尽量多的程序,因此不难想到需要用贪心策略去解决此问题。选择最短长度程序段优先的方式作为贪心策略,将数组按从小到大的顺序排序,每次在数组中选择一个最小的程序放入程序段中,即可得到最优解。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,l;
cin>>n>>l;
int *a = new int[n];
for(int i = 0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int ct = 0;
for(int j = 0;j<n;j++){
if(l-a[j]>=0){
ct++;
l-=a[j];
}
else break;
}
cout<<ct;
return 0;
}
反证法证明:假设程序P={1, 2, ...,n}按程序在磁带上的长度非递减排列,则程序1的长度最小。
我们假设A为最优解,且最先放进磁带的是程序k,若k=1,则A是一个以贪心选择开始的最优解。
若k>1,我们令B=A–{k}∪{1},因为程序 1 的长度小于程序 k 的长度,且 A中的程序个数与B相同,故B也是一个最优解,而B包含程序1,故总存在以贪心选择开始的最优存储方案。
时间复杂度分析:程序中复杂度最高的语句为遍历数组寻找最小值以及输入数组,故时间复杂度为O(n)。
贪心算法,顾名思义就是在解决问题的时候只考虑局部最优解的性质。与动态规划最大的不同就是贪心法没有“瞻前顾后”的过程,因此贪心算法求解效率高,代码和思想也更加简单。我们使用贪心算法求解时,需要先考虑问题是否满足贪心选择性质和最优子结构性质,必要时举适当反例判断贪心策略是否正确,确定这两条性质之后才能使用贪心算法。