算法实践7 投资问题
问题:
设\(m\)万元钱,\(n\)项投资,函数\(f_i(x)\)表示将\(x\)万元投入到第\(i\)项项目所产生的效益,\(i=1,2,\dots,n\)。问:如何分配这\(m\)万元,使得投资的总收益最高。
解析
设\(dp[i][j]\)为在前\(i\)个项目中投入\(j\)元能获得的最大收益。当\(i = 1\)时,我们从\(0\)推到\(1\)是显然正确的。那么当前一个项目在花\(m_1\)万元的最优解确定下来之后,我们能够枚举当前项目花\(m_2\)万元,从而在有向图上覆盖到所有合法的点,最终处理出最优解。
设计
for 枚举项目
for 枚举花费
for 枚举第i个项目花费q
dp[i][j] = max(dp[i][j], dp[i - 1][j - q] + w[i][q]);
分析
三层循环,时间复杂度\(O(nm^2)\)。
源码
https://github.com/Sstee1XD/Algorithm_homework/tree/main/实验7 投资问题
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
const int N = 1e3 + 7;
int w[N][N];
int dp[N][N];
int n, m, k;
void solve() {
cin >> n >> k >> m; // n个项目,每个项目能投资0~k,资金m
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= k; ++j) {
cin >> w[i][j];
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++ j) {
if (j > i * k) break;
dp[i][j] = 0;
}
}
for (int i = 1; i <= n; ++i) { // 第i个项目
for (int j = 1; j <= m; ++j) { // 总共花费j
if (j > i * k) break;
for (int q = min(k, j); q >= 0; --q) { // 第i个项目花费q
dp[i][j] = max(dp[i][j], dp[i - 1][j - q] + w[i][q]);
}
}
}
if (m > n * k) m = n * k; // 特判,当然也可以在转移方程时多一步
cout << dp[n][m] << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int t = 1;
while (t--) solve();
return 0;
}
/*
5 5 10
1 2 3 4 5
11 12 13 14 15
0 5 10 15 20
2 10 30 32 40
20 21 22 23 24
*/

浙公网安备 33010602011771号