动态规划之投资问题
问题:
设有m元钱,n项投资项目,函数fi(x)表示将x元投入到第i项项目中所产生的效益,i=1,2,3…n;
问:如何分配这m元钱,使得投资的总效益最高?
思路解析
将问题分成若干子问题,先考虑对第一个项目的分配,接着考虑前2个项目的分配,
...以此类推,考虑到n个项目的分配。
F1(x)=f1(1)=11, F2(x)=f2(2)=12, …以此类推
递推方程与边界条件
Fk(x)表示x万元投给前k个项目的最大收益
核心代码
int MaxInterest(int ms[M][M], int f[M][M], int s[M][M], int m, int n)
{
for (int i = 1; i <= n; i++) {//i为项目数,i个项目
for (int j = 0; j <= m; j++) {//循环 第i个项目投入m万元
ms[i][j] = 0;
for (int k = 0; k <= j; k++) {//循环按j万元对前i个项目投资并查找最大收益
if (ms[i][j] <= f[i][k] + ms[i - 1][j - k])
{
ms[i][j] = f[i][k] + ms[i - 1][j - k];
s[i][j] = k; //标记投入j万元最大收益时,分配给第i项的金额
}
}
}
}
return ms[n][m]; //将所求的最大收益值返回
}
三层循环实现找到最大收益及备忘录
s[i][j]数组为标记函数,记录每次投入j万元获取最大收益时,第i个项目所投资金额
ms[][]数组记录投入j万元分配到i个项目时的最大收益
完整代码
#include <iostream>
#include <math.h>
#include<iomanip>
using namespace std;
const int M = 8;//定义静态变量
void Display(int ms[M][M], int f[M][M], int s[M][M], int m, int n) {
int i, j, k = 1;//输出表格形式
cout << "------------------------------------------------------------------------------------------" << endl;
cout << "x" << setw(10) << "F1(x)" << setw(10) << "x1(x)" << setw(10) << "F2(x)" << setw(10) << "x2(x)" << setw(10) << "F3(x)" << setw(10) << "x3(x)" << setw(10) << "F4(x)" << setw(10) << "x4(x)" << endl;
for (i = 1; i <= m; i++) {
cout << k++ << " ";
for (j = 1; j <= n; j++) {
cout << setw(8) << ms[j][i] << setw(10) << s[j][i] << " ";//输出投资i万元且收益最大时第j个项目所分配的金额
}
cout << endl;
}
cout << "------------------------------------------------------------------------------------------" << endl;
int a[M] = { 0 };//初始化a数组
int t;
int g = 1;
for (int x = n; x > 0; x--) {
a[x] = s[x][m];//计算得出逆序最优分配解,逆向导入a[M]数组
t = s[x][m];//通过标记函数追溯最优解
m = m - t;
}
cout << "分配方案为:";
for (int i = 1; i <= n; i++) {
cout << "x" << i << " " << "=" << " " << a[i] << " ";//正向输出分配方案
}
cout << endl;
}
int MaxInterest(int ms[M][M], int f[M][M], int s[M][M], int m, int n)
{
for (int i = 1; i <= n; i++) {//i为项目数,i个项目
for (int j = 0; j <= m; j++) {//循环 第i个项目投入m万元
ms[i][j] = 0;
for (int k = 0; k <= j; k++) {//循环按m万元对前i个项目投资并查找最大收益
if (ms[i][j] <= f[i][k] + ms[i - 1][j - k])
{
ms[i][j] = f[i][k] + ms[i - 1][j - k];
s[i][j] = k; //标记投入j万元最大收益时,分配给第i项的金额
}
}
}
}
Display(ms, f, s, m, n);//调用打印函数
return ms[n][m]; //将所求的最大收益值返回
}
int main()
{
int ms[M][M] = { 0 }; int g[M][M] = { 0 };//初始化数组
int f[M][M] = { {0,0,0,0,0,0}, //数据导入
{0,11,12,13,14,15},
{0,0,5,10,15,20},
{0,2,10,30,32,40},
{0,20,21,22,23,24} };
cout << "投资5万元给4个项目的投资备忘录:" << endl;
cout << "个人最大利益:" << MaxInterest(ms, f, g, 5, 4) << "万元" << endl;
return 0;
}
}