1.问题
- 一般性描述:
- 设m万元钱,n项投资,函数fi表示将x万元投入第i项项目所产生的效益,i=1,2,…,n.
- 问:如何分配这m元钱,使得投资的总效益最高?
- 组合优化问题:
- 假设分配给第i个项目的钱数是x_i,问题描述为:
- 目标函数:max{f1(x1)+f2(x2)+…+f3(x3)}
- 约束条件:x1+x2+…+xn=m,xi
∈
\in
∈n
- 实例
投资效益表(m=5,n=4)
2.解析
- 设F
k
_k
k(x)表示x万元投资给前K个项目的最大收益,k
∈
\in
∈[1,2,…,n]
- 设x
k
_k
k(y)表示y元投资给第k个项目,k
∈
\in
∈[1,2,…,n]
- 递推方程:F
k
_k
k(x)=max{f
k
_k
k(x)+f
k
_k
k
−
_-
−
1
_1
1(x-x
k
_k
k)}
- 边界条件:F
1
_1
1(x)=f
1
_1
1(x),F
k
_k
k(0)=0,k=1,2,…,n
从表格中可以得出,投资项目1:1万元,项目3:3万元,项目4:1万元为最优选择,可得 61万元。
3.设计
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1000;
int n,m,x;
int f[N][N],F[N][N];
int main() {
cin>>n>>m;
for (int j=0;j<=m;j++) {
for (int i=1;i<=n;i++) {
cin>>f[i][j];
}
}
for (int i=1;i<=n;i++) {
for (int j=0;j<=m;j++) {
for (int k=0;k<=j;k++) {
F[i][j] = max(F[i][j],F[i-1][j-k] + f[i][k]);
}
}
}
cout<<"最大收益="<<F[n][m];
return 0;
}
4.分析
- F
k
_k
k(x)=max{f
k
_k
k(x)+f
k
_k
k
−
_-
−
1
_1
1(x-x
k
_k
k)}
- F
k
_k
k(x)=f
k
_k
k(x)
- x
k
_k
k
∈
\in
∈[0,…,x],共x+1项,因此有x+1次加,x项比较出最大值。
- For k=1,2,3…,n
- For x=1,2,3,…,m
- 加法
∑
k
=
2
n
\displaystyle\sum_{k=2}^{n}
k=2∑n
∑
x
=
1
m
(
x
+
1
)
\displaystyle\sum_{x=1}^{m} (x+1)
x=1∑m(x+1)=[(n-1)* m *(m+3)]/2
- 比较
∑
k
=
2
n
\displaystyle\sum_{k=2}^{n}
k=2∑n
∑
x
=
1
m
x
\displaystyle\sum_{x=1}^{m} x
x=1∑mx=[(n-1)* m *(m+1)]/2
- 复杂度W(n,m)=O(n*
m
2
m^2
m2)
5.源码
投资问题源代码