投资组和求最大利润
题目:
投资人出资一笔费用mount,投资给不同的公司(A,B,C....),求最大获取利润?
例如:投资400百万,给出两家公司A和B:
1.如果投资一百万给A公司,投资3百万给B工资,则获取14百万(5百万+9百万);
2.如果都投资给B公司,则获取15百万,所以应该投资给B公司;
故选择全部投给B公司。
Invested Amount(Unit: KRW 100 million won) | Company A | Company B |
1 | 5 | 1 |
2 | 6 | 5 |
3 | 7 | 9 |
4 | 8 | 15 |
条件:
1、给出投资额mount,以及公司个数comp
2、投给同一家公司的金额不能拆分,比如,有4百万投资额,投给A公司1百万和3百万(不允许)
代码:
/* 思路分析: 1,01背包问题,最早尝试把所有的点转换为 (公司数*投资数)个物品,进行简单的二重循环的背包问题,但是题意有说明,同一家 公司的投资不能分开,也就是这些物品之间有了排斥关系; 2,转换思路为,F[N][V]代表在前N家公司投资的总利益,应为投给了第N家和没有投给第N家两种情况的最大值; F[N][V] = MAX{F[N-1][V], F[N-1][?]+?}; 关键是这里投给第N家公司的最大利益需要一一遍历它的所有可能的投资数,然后得到max值,再代入上式进行比较即可。 int max = -1; for(int k = 1; k <= Mount; k++) if(j - k >= 0) max = MAX(max, dp[j-k] + invest[k][i]); */ #include <cstdio> #include <iostream> #include <cstring> using namespace std; #define MAX(a, b) ((a) > (b) ? (a) : (b)) int invest[301][21]; int Mount, Comp; int dp[301]; int main(int argc, char** argv) { int tc, T; //freopen("input_businessinvestment.txt", "r", stdin); cin >> T; for(tc = 0; tc < T; tc++) { cin >> Mount >> Comp; memset(dp, 0, sizeof(dp)); for(int i = 1; i <= Mount; i++) for(int j = 0; j <= Comp; j++) cin >> invest[i][j]; for(int i = 1; i <= Comp; i++) for(int j = Mount; j >= 1; j--) { int max = -1; for(int k = 1; k <= Mount; k++) if(j - k >= 0) max = MAX(max, dp[j-k] + invest[k][i]); dp[j] = MAX(max, dp[j]); } cout << dp[Mount] << endl; } return 0; }
输入文件:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
5 4 2 1 3 3 2 4 4 3 7 6 4 8 8 7 2 1 3 3 2 4 4 3 7 6 4 8 8 5 10 10 6 13 13 7 15 15 5 3 1 4 4 3 2 6 7 6 3 8 8 9 4 13 13 13 5 15 14 15 10 3 1 4 4 3 2 6 7 6 3 8 8 9 4 13 13 13 5 15 14 15 6 19 18 19 7 20 20 20 8 23 25 23 9 27 27 26 10 31 31 31 5 5 1 3 4 6 2 6 2 11 10 10 9 11 3 12 12 13 14 13 4 18 17 19 19 18 5 23 26 24 25 24