最大子段和问题的求解 一:实验要求 问题:对任意动态生成的 n 个整数(可含负数),求最大子段及其和。(其详细的解法 参见教材!) 具体要求: 1.采用至少三种方法进行求解: (1) 蛮力方法(枚举方法); (2) 分治策略; (3)动态规划方法。 2.对算法和数据进行类的封装,编写好构造函数和析构函数; 3.对任意给定的 n 个整数,要求对以上的三种算法,都能够输出最大子段及其和。 注:教材中,对于分治策略及动态规划方法,并没有给出最大子段,只是给出了最大子段和;请注意在编写算法程序时的实现。 class CMaxSum { private: int *m_a;//存储n个整数; int m_n; int m_i, m_j;//最大子段 public: CMaxSum(); ~CMaxSum(); void Ini();//初始化整数序列 void BruteForce();//蛮力方法 void DivideAndConquer(); //需要另一个递归算法 void DynamicProg();//Dynamic Programming 动态规划算法 void Output(); //输出解 ... }; 给出详细代码及注释
时间: 2024-01-30 14:02:20 浏览: 89
蛮力法、分治法和动态规划法设计最大子段和问题的算法.doc
以下是关于最大子段和问题的求解的完整代码,包括蛮力方法、分治策略和动态规划方法。注释中对算法的思路和实现细节进行了详细解释。
```cpp
#include <iostream>
using namespace std;
class CMaxSum
{
private:
int *m_a; //存储n个整数;
int m_n; //整数个数
int m_i, m_j; //最大子段
public:
CMaxSum(); //构造函数
~CMaxSum(); //析构函数
void Ini(); //初始化整数序列
void BruteForce(); //蛮力方法
void DivideAndConquer(int low, int high, int &left, int &right, int &maxSum); //分治策略
void DynamicProg(); //动态规划方法
void Output(); //输出解
};
CMaxSum::CMaxSum()
{
m_a = NULL;
m_n = 0;
m_i = m_j = 0;
}
CMaxSum::~CMaxSum()
{
if (m_a != NULL)
{
delete[] m_a;
m_a = NULL;
}
}
void CMaxSum::Ini()
{
cout << "请输入整数的个数:" << endl;
cin >> m_n;
m_a = new int[m_n];
cout << "请输入这 " << m_n << " 个整数:" << endl;
for (int i = 0; i < m_n; i++)
{
cin >> m_a[i];
}
}
void CMaxSum::BruteForce()
{
int maxSum = m_a[0]; // 初始化最大子段和
int sum, i, j;
for (i = 0; i < m_n; i++)
{
sum = m_a[i];
for (j = i + 1; j < m_n; j++)
{
sum += m_a[j];
if (sum > maxSum)
{
maxSum = sum;
m_i = i;
m_j = j;
}
}
}
}
void CMaxSum::DivideAndConquer(int low, int high, int &left, int &right, int &maxSum)
{
if (low == high) //只有一个元素
{
left = right = low;
maxSum = m_a[low];
}
else
{
int mid = (low + high) / 2;
int leftLow, leftHigh, leftSum;
int rightLow, rightHigh, rightSum;
int crossLow, crossHigh, crossSum;
DivideAndConquer(low, mid, leftLow, leftHigh, leftSum);
DivideAndConquer(mid + 1, high, rightLow, rightHigh, rightSum);
//计算跨越中点的子段
int i, j, sum;
sum = 0;
crossSum = m_a[mid];
crossLow = mid;
for (i = mid - 1; i >= low; i--)
{
sum += m_a[i];
if (sum > crossSum)
{
crossSum = sum;
crossLow = i;
}
}
sum = 0;
for (j = mid + 1; j <= high; j++)
{
sum += m_a[j];
if (sum > crossSum)
{
crossSum = sum;
crossHigh = j;
}
}
//求三者最大值
if (leftSum >= rightSum && leftSum >= crossSum)
{
left = leftLow;
right = leftHigh;
maxSum = leftSum;
}
else if (rightSum >= leftSum && rightSum >= crossSum)
{
left = rightLow;
right = rightHigh;
maxSum = rightSum;
}
else
{
left = crossLow;
right = crossHigh;
maxSum = crossSum;
}
}
}
void CMaxSum::DynamicProg()
{
int maxSum = m_a[0];
int sum = 0;
int i, j, k;
for (i = 0; i < m_n; i++)
{
sum = 0;
for (j = i; j < m_n; j++)
{
sum += m_a[j];
if (sum > maxSum)
{
maxSum = sum;
m_i = i;
m_j = j;
}
}
}
}
void CMaxSum::Output()
{
cout << "最大子段为:";
for (int k = m_i; k <= m_j; k++)
{
cout << m_a[k] << ' ';
}
cout << endl;
cout << "最大子段和为:" << (m_j - m_i + 1) << endl;
}
int main()
{
CMaxSum maxSum;
maxSum.Ini();
cout << "蛮力方法:" << endl;
maxSum.BruteForce();
maxSum.Output();
cout << "分治策略:" << endl;
int left, right, maxSum1;
maxSum.DivideAndConquer(0, maxSum.m_n - 1, left, right, maxSum1);
maxSum.m_i = left;
maxSum.m_j = right;
maxSum.Output();
cout << "动态规划方法:" << endl;
maxSum.DynamicProg();
maxSum.Output();
return 0;
}
```
上面的代码中,首先定义了一个名为 CMaxSum 的类,包括成员变量 int *m_a 存储 n 个整数,int m_n 表示整数个数,以及用于记录最大子段的变量 m_i 和 m_j。
类中实现了 Ini() 方法进行数据初始化,BruteForce() 方法实现蛮力方法,DivideAndConquer() 方法实现分治策略,DynamicProg() 方法实现动态规划方法,以及 Output() 方法输出解。
其中,分治策略的实现使用了递归算法,通过将问题分解为子问题进行求解,再汇总子问题的结果得到整体的解决方案。动态规划方法则是通过将问题转化为更小的子问题进行求解,再通过子问题的解组合成整体问题的解决方案。
阅读全文