• 算法分析设计实践——投资问题


    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

  • 相关阅读:
    git的使用
    本体建模
    word2vec改进之Negative Sampling
    word2vec改进之Hierarchical Softmax
    word2vec原理
    Window下mysql的安装
    PageRank算法
    集成学习-------简单介绍
    自我介绍
    Apollo学习笔记(二):循迹实现过程
  • 原文地址:https://www.cnblogs.com/DreamACMer/p/12700908.html
Copyright © 2020-2023  润新知