• (学习7)动态规划——投资问题


    动态规划是一种算法设计技术。

    特点 1:由交叠的子问题构成;特点2:满足最优法;

    投资问题:

    有n个项目,有m元可以去投资,列出每个项目的投资与收益情况,问该如何分配这m元?

    投入(m) 项目1(f1/x1) 项目2(f2/x2) 项目3(f3/x3) 项目4(f4/x4)
    0 0 0 0 0
    1 11 0 2 20
    2 12 5 10 21
    3 13 10 30 22
    4 14 15 32 23
    5 15 20 40 24

    这个问题满足的约束条件为:x1+x2+x3+x4=m

    目标函数:max{f1(x1)+f2(x2)+f3(x3)+f4(x4)}

    一个推论:一个最优策略的任何子序列一定相对于该子序列开始与结束的最优决策序列。

    伪代码:

    memset(Fx,0,sizeof(Fx)); //初始化都为0
    for (int k=1;k<=n;k++)  //前k个项目
      for(int x=1;x<=m;x++) //投入x元
         for(int z=0;z<=x;z++)  //投入项目k为z元
            Fx[k][x]=max(Fx[k][x],Fx[k-1][x-z]+f[k][z]);

    解析(第一次纯手工dp后,用电子稿写出来......):

    n=1
    F[1][0]=0  F[1][1]=11    MAX(F[1][1])=11
    F[1][0]=0  F[1][1]=11 F[1][2]=12   MAX(F[1][2])=12
    F[1][0]=0  F[1][1]=11 F[1][2]=12 F[1][3]=13  MAX(F[1][3])=13
    F[1][0]=0  F[1][1]=11 F[1][2]=12 F[1][3]=13  F[1][4]=14  MAX(F[1][4])=14
    F[1][0]=0  F[1][1]=11 F[1][2]=12 F[1][3]=13  F[1][4]=14  F[1][5]=15  MAX(F[1][5])=15
    n=2
    F[2][0]=11  F[2][1]=0    MAX(F[2][1])=11
    F[2][0]=12  F[2][1]=11  F[2][2]=5   MAX(F[2][2])=12
    F[2][0]=13   F[2][1]=12  F[2][2]=16  F[2][3]=10  MAX(F[2][3])=16
    F[2][0]=14   F[2][1]=13  F[2][2]=17  F[2][3]=21  F[2][4]=15  MAX(F[2][4])=21
    F[2][0]=15  F[2][1]=14  F[2][2]=18 F[2][3]=22   F[2][4]=26  F[2][5]=20  MAX(F[2][5])=26
    
    n=3
    F[3][0]=11  F[3][1]=2    MAX(F[3][1])=11
    F[3][0]=12  F[3][1]=13  F[3][2]=10   MAX(F[3][2])=13
    F[3][0]=16   F[3][1]=14  F[3][2]=21  F[3][3]=30  MAX(F[3][3])=30
    F[3][0]=21   F[3][1]=18  F[3][2]=22  F[3][3]=41  F[3][4]=32  MAX(F[3][4])=41
    F[3][0]=26  F[3][1]=23  F[3][2]=26 F[3][3]=42   F[3][4]=43  F[3][5]=40  MAX(F[3][5])=43
    
    
    n=4
    F[4][0]=11  F[4][1]=20    MAX(F[4][1])=20
    F[4][0]=13  F[4][1]=31  F[4][2]=34   MAX(F[4][2])=34
    F[4][0]=30   F[4][1]=33  F[4][2]=32  F[4][3]=22  MAX(F[4][3])=33
    F[4][0]=41   F[4][1]=50  F[4][2]=35  F[4][3]=34  F[4][4]=23  MAX(F[4][4])=50
    F[4][0]=43  F[4][1]=61  F[4][2]=51 F[4][3]=35   F[4][4]=34  F[4][5]=24  MAX(F[4][5])=61
    
    最后输出的MAX(F[4][5])=61即为最大收益

    源代码

    //
    //  main.cpp
    //  作业7
    //
    //  Created by yizhihenpidehou on 2020/4/7.
    //  Copyright © 2020 yizhihenpidehou. All rights reserved.
    //
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int maxen=200;
    int Fk[maxen][maxen]={0};//存放第k个项目投资x元可以获得的最大收益
    int fk[maxen][maxen]={0};//存放第k个项目x元可以获得的收益
    int dp(int n,int m){
        for(int k=1;k<=n;k++){//前k个项目
            for(int x=1;x<=m;x++){//前K个项目共投资多少钱
                for(int z=0;z<=x;z++){//给第K个项目分配多少钱
                    Fk[k][x]=max(Fk[k][x],fk[k][z]+Fk[k-1][x-z]);
                    //计算钱该怎么分配给第k个项目与前k-1个项目收益最大
                }
            }
        }
        return Fk[n][m]; //返回收益最大的情况(因为每次Fk[k][x]都是存最大收益)
    }
    int main(int argc, const char * argv[]) {
        int n=4,m=5;//有4个项目,共有5万元
        memset(Fk,0,sizeof(Fk));
        memset(fk,0,sizeof(fk));
        fk[1][0]=0;fk[1][1]=11;fk[1][2]=12;fk[1][3]=13;fk[1][4]=14;fk[1][5]=15;
        fk[2][0]=0;fk[2][1]=0;fk[2][2]=5;fk[2][3]=10;fk[2][4]=15;fk[2][5]=20;
        fk[3][0]=0;fk[3][1]=2;fk[3][2]=10;fk[3][3]=30;fk[3][4]=32;fk[3][5]=40;
        fk[4][0]=0;fk[4][1]=20;fk[4][2]=21;fk[4][3]=22;fk[4][4]=23;fk[4][5]=24;
        int maxx=dp(n,m);
        printf("maxx:%d
    ",maxx);
        return 0;
    }
    View Code

    时间复杂度:O(nm²)

     

  • 相关阅读:
    python2和3切换时的几个注意点会报错
    Python异常UnicodeEncodeError 'gbk' codec can't encode character 'xa0'
    python爬虫使用Xpath爬取指定位置的内容
    问题账户需求分析
    2018年春季个人阅读计划
    我们应当怎样做需求分析
    人月神话读后感3
    人月神话读后感2
    线程池
    生产者消费者
  • 原文地址:https://www.cnblogs.com/pipihoudewo/p/12656257.html
Copyright © 2020-2023  润新知