434
社区成员
发帖
与我相关
我的任务
分享请说明作业三”程序存储问题“的贪心策略,并用反证法证明满足贪心选择性质,并给出时间复杂度分析
设有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
贪心策略:
(1)将要存取的n个程序的磁带长度按从小到大进行排序。
(2)每次将长度最小的程序放入磁带上,将文件个数加一并更新磁带上的长度,直至磁带上的长度放不下长度最小的程序。
反证法证明满足贪心选择性质:在第一次可以选择最小程序的前提下,假设在最优解中去掉第一次选择的最小程序后得到的子问题的最优解的t0大于原问题最优解的t1,那么将最小程序加入选择产生的解的t2大于t1,此时t1不是最优解,这不成立。故此问题具有最优子结构性质。
时间复杂度:排序O(nlogn) + 循环O(n),故时间复杂度为O(nlogn)
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,L;
int l[N];
int main()
{
cin>>n>>L;
for(int i=0;i<n;i++) cin>>l[i];
sort(l,l+n);
int res=0;
for(int i=0;i<n;i++)
if(l[i]<=L)
{
L-=l[i];
res++;
}
cout<<res<<endl;
return 0;
}
2.你对贪心算法的理解
所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。贪心算法的难点在于如何找到合适的贪心选择,并能够证明这个选择是正确的。