144
社区成员
发帖
与我相关
我的任务
分享目录
2. 以{0-1}背包问题和背包问题为例,讨论动态规划算法与贪心算法的异同
3. 算法实验2:完成教材114页算法实现题4-2,总结实验出现问题及解决方法
4. 算法实验2:完成教材118页算法实现题4-14,总结实验出现问题及解决方法
贪心算法通过一系列选择来得到问题的解,所做的每个选择都是当前状态下局部最好的选择,即贪心选择。这种启发式的策略并不总能奏效,但在许多情况下确能达到预期目的。
贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这也是贪心算法和动态规划算法的主要区别。在动态规划算法中,每步所做的选择往往依赖于相关子问题的解,因而只有在解出相关子问题后,才能做出选择。而在贪心算法中,仅在当前状态下做出最好选择,即局部最优选择。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每步所做的贪心选择最终导致问题的整体最优解。
最优子结构性质:当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可以用动态规划算法或贪心算法求解的关键特征。
通过本章的学习,我学会了贪心算法的原理,知道了贪心算法和动态规划算法的异同。于我而言,贪心算法在算法设计和理解上比动态规划算法更加简单直接,对于既可以用贪心算法和动态规划算法的问题,可以优先使用贪心算法。判断一个问题是否可以用这两种算法,首选要判断问题是否具有最优子结构性质,如果有则至少可以使用动态规划算法。如果有且问题的整体最优解可以通过一系列局部最优的选择来达到,则也可以使用贪心算法。如果没有最优子结构,则不能使用这两种算法。
相同点:贪心算法和动态规划算法都要求问题具有最优子结构性质。
不同点:贪心算法可以求解背包问题,但是不能求解{0-1}背包问题。因为在{0-1}背包问题中,贪心算法无法保证最终将背包装满,部分闲置的背包空间使得每千克背包空间的价值降低了。

#include<iostream>
#include<algorithm>
using namespace std;
int a[1000]; //升序数组
int b[1000]; //降序数组
int cmp(int x, int y) //降序排序
{
return x > y;
}
void Min(int a[], int n) //最少比较次数
{
int min = 0;
for (int i = 0; i < n - 1; i++) //n个数,需要排序n-1次
{
sort(a + i, a + n);
a[i + 1] = a[i] + a[i + 1];
min = min + a[i + 1] - 1;
}
cout << min;
}
void Max(int b[], int n) //最多比较次数
{
int max = 0;
for (int i = 0; i < n - 1; i++) //n个数,需要排序n-1次
{
sort(b + i, b + n, cmp); //降序排序
b[i + 1] = b[i] + b[i + 1];
max = max + b[i + 1] - 1;
}
cout << max << endl;
}
int main()
{
int k;
cin >> k;
for (int i = 0; i < k; i++)
{
cin >> a[i];
b[i] = a[i];
}
Max(b, k);
Min(a, k);
return 0;
}



#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int main()
{
int n, k;
int maxcount=0, mincount = 0;
cin >> n >> k;
vector<int> a;
for (int i = 0; i < n; i++) {
int e;
cin >> e;
a.push_back(e);
}
priority_queue<int, vector<int>, greater<int>>q1;
priority_queue<int, vector<int>, less<int>>q2;
for (int i = 0; i < (int)a.size(); i++)
{
q1.push(a[i]);
q2.push(a[i]);
}
int c = 0, temp = 0;
while (q1.size())
{
mincount += q1.top();
if (q1.size() >= k)
{
++c;
temp += q1.top();
}
q1.pop();
if (c == k)
{
c = 0;
q1.push(temp);
temp = 0;
}
}
temp = 0;
while (q2.size())
{
if (q2.size() == 1)
q2.pop();
else
{
maxcount += q2.top();
temp += q2.top();
q2.pop();
maxcount += q2.top();
temp += q2.top();
q2.pop();
q2.push(temp);
temp = 0;
}
}
cout << mincount << ' ' << maxcount << endl;
return 0;
}
