1.问题
设m元钱,n项投资,函数fi(x)表示将x元投入第i项项目所产生的相依 I = 1 , 2 …. N
问:如何分配这m元钱,使得投资的总效益最高。
2.解析
1.我们设dp[i][j]为前i个项目花费j元所能得到的最大收益
2.假设我们分配个第i个项目k元, 那么实际上前i-1个项目一共得到了j – k元
因此 dp[i][j] 的最优状态 可以由 dp[I - 1][j - k] + fi (k)中的最优子决策得到。
3.设计
for (int i = 1; i <= n; ++i) { for (int j = 0; j <= m; ++j) { for (int k = 0; j + k <= m; ++k) { dp[i][j + k] = max(dp[i - 1][j] + val[i][k], dp[i][j + k]); /* 我们在前i个项目已经花了j+k万元 在第i个项目花了k万元 dp[i][j + k] 就可以后 dp[i - 1][j] + val 转移得到 所以有转移方程式:dp[i][j + k] = max(dp[i - 1][j] + val[i][k], dp[i][j + k]); */ } } }
4.分析
时间复杂度 : O(n * m * m)
空间复杂度 : O (n * m)
5.源码

1 #include<cstdio> 2 #include<string.h> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 7 8 int n, m; // n代表项目的数量 , m代表投资的金额 9 int val[1000][1000]; // 用户存储给第i个项目投资x万元,能够获得val[i][x]万元的收益 10 int dp[1000][1000] = {0}; // dp[i][j]表示到第i个项目的时候已经花费了j万元的最大收益 11 int main() 12 { 13 14 scanf("%d %d", &n, &m); 15 for (int i = 1; i <= n; ++i) 16 { 17 for (int j = 0; j <= m; ++j) 18 { 19 scanf("%d", &val[i][j]); // 对第i个项目投资j万元的收益为val[i][j] 20 } 21 } 22 23 for (int i = 1; i <= n; ++i) 24 { 25 for (int j = 0; j <= m; ++j) 26 { 27 for (int k = 0; j + k <= m; ++k) 28 { 29 dp[i][j + k] = max(dp[i - 1][j] + val[i][k], dp[i][j + k]); 30 /* 31 我们在前i个项目已经花了j+k万元 32 在第i个项目花了k万元 33 dp[i][j + k] 就可以后 dp[i - 1][j] + val 转移得到 34 所以有转移方程式:dp[i][j + k] = max(dp[i - 1][j] + val[i][k], dp[i][j + k]); 35 */ 36 } 37 } 38 } 39 cout << dp[n][m] << endl; 40 return 0; 41 } 42 43 44 /* 45 样例输入: 46 4 5 47 0 11 12 13 14 15 48 0 0 4 10 15 20 49 0 2 10 30 32 40 50 0 20 21 22 23 24 51 样例输出: 52 61 53 */
https://github.com/BambooCertain/Algorithm.git