动态规划——投资问题
问题:
m万元钱,n个投资项目,函数fi (x)表示将x元钱投入第i个项目所产生的效益,i=1,2,…n。如何分配这m元钱,使得投资的总效益最高?
分析:
F[x][k]:x万元投给前k个项目的收益
f[xk][k]:xk万元投给第k个项目的收益
F[x][k] = f[x][1],k = 1;max_0<=xk<=x_{f[xk][k]+F[x-xk][k-1]},k>1;
初始化F[x][1] = f[x][1]
代码:
#include <bits/stdc++.h>
using namespace std;
// 计算投资最大收益
// 输入:m万元,n个项目,前k个项目投资x万元收入F[x][k],第k个项目投资xk万元收入f[xk][k],
// 结果记录矩阵x万元投入前k个项目获得最高收益则第k个项目应投a[x][k]万元
void invest(int m, int n, int F[][5], int f[][5], int a[][5]){
// 初始化
for(int i = 1;i <= m;i++){
F[i][1] = f[i][1];
a[i][1] = i;
}
// 计算
for(int k = 2;k <= n;k++)
for(int x = 1;x <= m;x++){
int maxF = -1,money = -1;
for(int i = 0;i <= x;i++){
if(f[i][k]+F[x-i][k-1]>maxF){
maxF = f[i][k]+F[x-i][k-1];
money = i;
}
}
F[x][k] = maxF;
a[x][k] = money;
}
}
// 根据a[][]构造最优解
void traceback(int a[][5],int i ,int j){
if(i <= 0||j <= 0) return ;
traceback(a, i-a[i][j], j-1);
cout<<a[i][j]<<" ";
}
int main(){
int m = 5,n = 4;
int f[6][5] = {
{0,0,0,0,0},
{0,11,0,2,20},
{0,12,5,10,21},
{0,13,10,30,22},
{0,14,15,32,23},
{0,15,20,40,24}
};
int F[6][5] = {
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
};
int a[6][5];
memset(a, 0, sizeof(a));
invest(m, n, F, f, a);
cout<<F[5][4]<<endl;
traceback(a, 5, 4);
}
复杂度:
时间复杂度:O(nm2)
空间复杂度:O(nm)