实验7投资问题

问题:

设$m$元钱,$n$项投资,函数$f[i][x]$表示将$x$元投入第i项项目所产生的效益,$i=1,2,…,n$.问:如何分配这$m$元钱,使得投资的总效益最高?

解析:

背包问题。

设$dp[i][j]$表示在前$i$个项目投入$j$元所产生的最大效益。

转移方程为:

$dp[i][j] = max( dp[i][j] , dp[i - 1][ j - k] + f[i][k] )$

对于每个项目的投资,可以记录$x[i][j]$表示对于前$i$个项目总共投资$j$元时,对项目$i$的投资。

则对每个项目的投资可以由最后一个倒推回来。

$ans[i] = x[i][m] , m -= ans[i] $

设计(核心代码):

 1 for (int i = 1; i <= n; ++i)
 2 {
 3     for (int j = 0; j <= m; ++j)
 4     {
 5         for (int k = 0; k <= j; ++k)
 6         {
 7             if (dp[i][j] < dp[i - 1][j - k] + f[i][k])
 8             {
 9                 dp[i][j] = dp[i - 1][j - k] + f[i][k];
10                 x[i][j] = k;
11             }
12         }
13     }
14 }
15 ans[n] = x[n][m];
16 int tmp_m = m - ans[n];
17 for (int i = n - 1; i >= 1; --i)
18 {
19     ans[i] = x[i][tmp_m];
20     tmp_m -= ans[i];
21 }

分析:

复杂度:$O(nm^2)$

源码:

https://github.com/Big-Kelly/Algorithm

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int inf = 2e9 + 7;
 5 const ll Inf = 1e18 + 7;
 6 const int maxn = 3e3 + 5;
 7 const int mod = 1e9 + 7;
 8 
 9 int dp[maxn][maxn];  //dp[i][j]表示前i件投j元的最大收益
10 int f[maxn][maxn];   //f[i][j]表示第i件投资j元的最大收益
11 int x[maxn][maxn];   //x[i][j]表示前i件投入j元时第i件的投资
12 int ans[maxn];       //表示收益最大时每个的投资
13 
14 int main()
15 {
16     int n, m;
17     scanf("%d %d", &n, &m);
18     for (int i = 1; i <= n; ++i)
19     {
20         for (int j = 1; j <= m; ++j)
21         {
22             scanf("%d", &f[i][j]);
23         }
24     }
25     for (int i = 1; i <= n; ++i)
26     {
27         for (int j = 0; j <= m; ++j)
28         {
29             for (int k = 0; k <= j; ++k)
30             {
31                 if (dp[i][j] < dp[i - 1][j - k] + f[i][k])
32                 {
33                     dp[i][j] = dp[i - 1][j - k] + f[i][k];
34                     x[i][j] = k;
35                 }
36             }
37         }
38     }
39     ans[n] = x[n][m];
40     int tmp_m = m - ans[n];
41     for (int i = n - 1; i >= 1; --i)
42     {
43         ans[i] = x[i][tmp_m];
44         tmp_m -= ans[i];
45     }
46     printf("投资的最大收益是%d元
", dp[n][m]);
47     for (int i = 1; i <= n; ++i)
48     {
49         printf("对第%d个项目的投资为%d元
", i, ans[i]);
50     }
51 }
View Code
原文地址:https://www.cnblogs.com/zhang-Kelly/p/12694137.html