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;
    }
  • 相关阅读:
    IIS发布MVC出错
    dynamic
    设计模式——简单工厂模式[已了解本质]
    Object和泛型
    sublime Text不能安装插件的解决办法
    .net MVC入门
    windows服务写完之后怎么让它跑起来
    sql数据库连接字符串在APP.config配置文件内的两种写法
    Sql语句里面调用变量
    Sql数据库不能频繁连接
  • 原文地址:https://www.cnblogs.com/xusi/p/12369711.html
Copyright © 2011-2022 走看看