zoukankan      html  css  js  c++  java
  • (基础)01背包问题

    问题描述

    有n个物品,它们有各自的体积ci和价值wi,现有给定容量的背包v,如何让背包里装入的物品具有最大的价值总和?

    原理:

      动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。

    思路:

      i为遍历的每一个物品,j为遍历0到v的体积,如果可以装下,由于装下不一定使总和最大,则装下即为dp[i-1][j-c[i]]+w[i],不装为dp[i-1][j],取两者中较大者。j-c[i]表示为目前物品空出空间,剩下的空间的价值取 之前可用空间下的最大值。

        由此可以得出递推关系式:

        1) j<c(i)      dp(i,j)=dp(i-1,j)

        2) j>=c(i)     dp(i,j)=maxdp(i-1,j)dp(i-1,j-c(i))+w(i)

    输入:

    5 10

    2 1

    3 5

    2 5

    3 4 

    4 3

    输出:

    9

    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const double PI=acos(-1.0);
    const int inf=0x7fffffff;
    int w[105],c[105];
    int dp[105][1000];
    int n,v,mx,sum; 
    
    int main(){
        cin>>n>>v;
        for(int i=1;i<=n;i++){
            cin>>w[i]>>c[i];
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<=v;j++){
                if(j>=c[i]){
                    dp[i][j]=max(dp[i-1][j-c[i]]+w[i],dp[i-1][j]);//结果取选改物品和不选改物品价值的最大值 
                }
                else{
                    dp[i][j]=dp[i-1][j];                        //空间不够,结果为之前的最大值 
                }
            }
        }
        cout<<dp[n][v];
        return 0; 
    }

     节约空间写法:

    #include <cstdio>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    const int inf=0x7fffffff;
    const long long mod=1e9+7;
    const double PI=acos(-1);
    int w[105],c[105];
    int dp[105];
    int main()
    {    
        int n,v;
        cin>>n>>v;
        for(int i=0;i<n;i++){
            cin>>w[i]>>c[i];
        }
        for(int i=0;i<n;i++){
            for(int j=v;j>=c[i];j--){
                dp[j]=max(dp[j-c[i]]+w[i],dp[j]);
            }
        }
        cout<<dp[v];
        return 0;
    }
  • 相关阅读:
    MySQL Connection排查未授权用户(unauthenticated user)
    Git常用命令
    abc
    更新显卡驱动
    财务模块 采购、接收、应付会计分录和功能认识
    ebs界面颜色改变
    获取科目的描述 创建科目
    EBS总账(GL)模块常用表
    收款 付款 到总帐
    PO收料到入库的分析
  • 原文地址:https://www.cnblogs.com/xusi/p/12369711.html
Copyright © 2011-2022 走看看