动态规划入门篇之01背包

                                        01背包

      背包什么情况?我们是来学习算法的,怎么变成背包了啊,其实01背包也就是一种形象的比喻吧!他就是一个大算法中的一个小小的分类,那就是动态规划,动态规划相信大家都听说过吧,动态规划是非常实用的一种算法,虽然他比较好用,但是就是不太好理解,但是当你真正学会01背包之后,你会感觉做题的时候如有神助!今天我们就先从01背包开始来学习动态规划。

      有n 种重量和价值分别为wivi 的物品,从这些物品中挑选总重量不超过W 的物品,求出挑选物品价值总和的最大值。在
这里,每种物品只可以挑选一件。官方解释。

       其实大致意思就是你有一个背包,但是背包能装的东西有限,现在有一些有重量和价值的物品,你要做的就是怎么装才能使你的背包装的价值最多。当然有的同学,第一感觉那肯定使贪心算法啊,就是先装最贵的,那么我们来举一个例子看看,假如你有一个容量为10的背包现在有三个物品,他们的体积和价值分别是v :9 4 6,对应的价值分别为w:10 8 6;从中可以看出第一个物品价值是最高的,如果我们背包装了第一个物品那么就放不下其他的物品了,所以此时背包的价值为10,可是我们也可以装第二个物品和第三个物品,这样装时此时背包的价值为8+6=14;从中可以看出贪心算法是错误的,所以我们是不能用贪心的,那么我们应该怎么做才能使背包装的东西的价值最贵呢?

         其实对每一个物品来说只有两种状态,那就装和不装,那么我们就从这两种状态出发,如果这个物品选了会是什么情况!如果这个物品不选又会是什么情况,我们先来举一个例子吧,假如现在我们有编号分别为a,b,c,d,e的五件物品,它们的重量分别是4,5,6,2,2,它们的价值分别是6,4,5,3,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?我们一个一个物品来看,首先看第一个物品,装的话此时背包的容量变为(10-4),背包的价值为6,不装的话背包的价值为0,所以肯定装啊,现在我们已经确定好第一个物品了,现在我们再来看第二个物品,装的话此时背包的容量变为(10-4-5),背包的价值为10,不装的话背包的价值为6,所以肯定装啊,再来看第三个物品,装的话此时背包的容量变为(10-4-5-6)<0了,装不下了,那怎么办呢,那就不装了?如果不装的话那么就没什么意义了啊,因为每次你都从第一个物品开始装,装的下就装,装不下就不装,这可怎么行呢?那怎么办呢?如果想装但是你又装不下怎么办?笨啊,那你不会腾出来一部分的空间啊,这样不就能装的下了,可是这我们又该怎么做呢?其实也很简单,我们只要看当背包(10-4-5+6)就行了是吧,此时的背包的·价值为多少呢?不知道?不知道?这怎么行,那怎么办呢,那你就再刚开始的时候就记录下来啊,所以啊我们把背包为10的背包分为10的背包,他们的容积分别为1,2,3,4,5,6,7,8,9,10,这样分好以后我们就有了下面的表格,请大家好好的理解一下这个表格,并好好的模拟一下

包,如何让背包里装入的物品具有最大的价值总和?

name weight value 1 2 3 4 5 6 7 8 9 10
a 2 6 0 6 6 9 9 12 12 15 15 15
b 2 3 0 3 3 6 6 9 9 9 10 11
c 6 5 0 0 0 6 6 6 6 6 10 11
d 5 4 0 0 0 6 6 6 6 6 10 10
e 4 6 0 0 0 6 6 6 6 6 6 6

首先要明确这张表是至底向上,从左到右生成的。

原理大家大概都清楚了吧,现在呢我们从一个例题出发,来讲述怎么用代码实现01背包:

涂奥最近迷上了吃鸡,房间有n个配件,每个配件有c(c<=1e3)的重量和v(v<=1e3)的价值,哇,涂奥捡了一个2级包,容量为s,所以涂奥最多当多肥的快递员呢?

Input

扫描二维码关注公众号,回复: 3026650 查看本文章

输入的第一行是T, 表示有一共要打T场比赛.

每组数据由三行组成.

第1行包含两个整数n和s 第2行包含n个整数, 表示每一个配件的价值. 第3行包含n个整数, 表示每个配件的重量.

Output

对每一组数据, 输出涂奥可以多肥.

Sample Input

1
10 10
1 3 5 7 9 11 13 15 17 19
19 17 15 13 11 9 7 5 3 1

Sample Output

51

 这就是一道典型的01背包问题,当然也是最基础的、

#include<stdio.h>
#include<string.h>
int v[1003],w[1003];
int dp[1003];
int MAX(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&v[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        for(int i=1;i<=n;i++)
        {
            for(int j=m;j>=w[i];j--)
                dp[j]=MAX(dp[j],dp[j-w[i]]+v[i]);
        }
        printf("%d\n",dp[m]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42757965/article/details/82048219