美文网首页动态规划
0-1 背包问题(动态规划)

0-1 背包问题(动态规划)

作者: 放下梧菲 | 来源:发表于2019-05-05 18:13 被阅读6次

题目描述
给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大?

在选择装入背包的物品时,对每种物品i只能有两种选择,装入或者不装入,不能装入多次,也不能部分装入。

输入
第一行输入物品的个数n。

第二行输入物品的重量序列w。(中间有空格)

第三行输入物品的价值序列v。(中间有空格)

第四行输入背包容量c。

输出
第一行输出装入背包的物品。(用0和1表示,中间无空格)

第二行输出最大价值。

样例输入
3
3 4 5
4 5 6
10
样例输出
011
11
背包问题是动态规划的最为基础的问题。初看背包问题,便知道肯定不是用贪心做法,直接选择用动态规划,那就是先分析问题,我们可以得到一个最优子结构,如果选n个物品,容量为c,得到一个最大值,那显然,选n-1个物品,容量为c 或者 c-第n个物品的重量的最大值是之前的一个最大值的子结构。因此我们不但能得到最优子结构,甚至还能知道转移方程该如何构造。dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]),这里的i是一直选到第i个物品,j是容量,那我们最终的答案是什么呢?如果知道这个,就明白了这个递推表达式的含义了,详情看代码。
本题还需要得到一个最优解,一般来说动态规划如果要求得最优解的话,是通过之前我们存放的那个dp表,来找规律的,然后通过回溯法来找到最优解。我已将dp表打印了出来,规律希望大家能找到,代码如下。

#include<iostream>
#define max(x,y) (x)>(y)?(x):(y)
using namespace std;
int f(int **dp,int n,int c,int *w,int *s){
    if(dp[n][c]==0){
        s[n]=0;
        return 0;
    }
    
    if(dp[n][c]!=dp[n-1][c]){
        s[n]=1;
        f(dp,n-1,c-w[n],w,s);
    }
    else{
        s[n]=0;
        f(dp,n-1,c,w,s);
    }
} 
void fun(int n,int *w,int *v,int c,int *s){
    int **dp=new int *[n+1];
    for (int i=0;i<=n;i++){
        dp[i]=new int [c+1];
    } 
    
    for(int i=0;i<=c;i++){
        dp[0][i]=0;
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<=c;j++){
            if(j>=w[i])
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
            else
                dp[i][j]=dp[i-1][j];
        }
    }
    for(int i=n;i>=1;i--){
        for(int j=1;j<=c;j++)
            cout<<dp[i][j]<<" ";
        cout<<'\n';
    } 
    f(dp,n,c,w,s);//构造最优解
    for(int i=1;i<=n;i++){
        cout<<s[i];
    }
    cout<<'\n';
    cout<<"背包内最大价值为"<<dp[n][c];
    delete []dp;
}
int main(){
    int n;
    cout<<"请输入n"<<endl;
    cin>>n;
    int w[n];
    int v[n];
    cout<<"请分别输入物品重量"<<endl; 
    for(int i=1;i<=n;i++){
        cin>>w[i];
    }
    cout<<"请分别输入物品价值"<<endl;
    for(int i=1;i<=n;i++){
        cin>>v[i];
    }
    int *s=new int [n+1];//存放最优解 
    int c;
    cout<<"请输入背包容量c"<<endl;
    cin>>c;
    fun(n,w,v,c,s);
} 

相关文章

  • 动态规划

    0-1背包问题 自己实现的0-1背包问题的动态规划解法,先贴上吧,动态规划原理解释有空再写。

  • 初识动态规划

    0-1 背包问题 备忘录 动态规划-二维数组 动态规划-一维数组 0-1 背包问题升级版 回溯算法 动态规划-二维...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 数据结构与算法笔记day23:动态规划

    1初识动态规划 这节课的内容不涉及动态规划的理论,而是通过两个例子:0-1背包问题、0-1背包问题升级...

  • 算法-动态规划-背包问题

    背包问题是基础的动态规划问题,包含了0-1背包,完全背包,多重背包等。 0-1背包 存在容量为 的背包 , 件体...

  • 背包问题

    背包问题属于典型的动态规划问题。这里我们将详细介绍0-1背包,完全背包和多重背包问题 一、 0-1背包 有N件物品...

  • 背包问题

    1、前言 背包问题是典型的动态规划问题,它有非常多的类型,本文讨论最常见的0-1背包问题 0-1背包问题描述:有一...

  • Algorithm

    bit manipulation 动态规划 0-1背包问题 寻找最小的k个数

  • 算法3:动态规划

    5.动态规划5.1 什么是动态规划?5.2 自底向上的动态规划:5.3 自顶向下的动态规划5.4 0-1背包问题:...

  • 动态规划-0-1背包问题

    动态规划-0-1背包问题 动态规划(dynamic programming)是解决多阶段决策问题常用的最优化理论,...

网友评论

    本文标题:0-1 背包问题(动态规划)

    本文链接:https://www.haomeiwen.com/subject/ecnhoqtx.html