今天写题的时候碰到了一道完全背包题,可是没有看出来,乱写了一通,浪费了一个晚上,顺便复习一下背包的知识

01背包

每种物品只能选择一次或者不选,求背包容量内的最大价值

先给出状态转移方程:

f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);

解释一下:f[i][j]表示的是前i个物品中,背包容量为j时,得到的最大价值;如果在容量为j时选择不放第i个物品,那么f[i][j]=f[i-1][j],f[i-1][j]表示前一个物品在容量j时的状态值;如果在容量为j时选择放第i个物品,那么f[i][j]=f[i-1][j-w[i]]+v[i],f[i-1][j-w[i]]+v[i]表示前一个物品得到的状态加上第i个物品的价值;自然而然,f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);

下面是二维数组的代码,自己敲了一遍,加深印象

 #include<cstdio>
int main()
{
int n,m,v[],w[],f[][];
scanf("%d %d",&m,&n);
for(int i=;i<=n;i++)
scanf("%d %d",&v[i],&w[i]);
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(w[i]<=j)
f[i][j]=max(f[i-][j],f[i-][j-w[i]]+v[i]);
else
f[i][j]=f[i-][j];
}
}
printf("%d",f[n][m]);
return ;
}

还有一种是一维数组的方法,更能节省空间

 #include<cstdio>
int main()
{
int n,m,v[],w[],f[];
scanf("%d %d",&m,&n);
for(int i=;i<=n;i++)
scanf("%d %d",&v[i],&w[i]);
for(int i=;i<=n;i++)
{
for(int j=m;j>=;j--)
{
if(w[i]<=j)
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
printf("%d",f[m]);
return ;
}

里面第二个循环为什么要倒着来,遍历到第i个物品时,f[j]应该与第i-1个物品的状态比较,如果顺着来的话,f[j]则与第i个物品的状态进行了比较,这样会出事的;

完全背包

每种物品可以选无数次,求背包容量内的最大价值

状态转移方程为:f[j]=max(f[j],f[j-w[i]]+v[i]);

贴上代码:

 #include<cstdio>
int main()
{
int n,m,v[],w[],f[];
scanf("%d %d",&m,&n);
for(int i=;i<=n;i++)
scanf("%d %d",&v[i],&w[i]);
for(int i=;i<=n;i++)
{
for(int j=w[i];j<=m;j++)
{
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
printf("%d",f[m]);
return ;
}

多重背包

每种物品能取有限次,求背包容量内的最大值

多重背包问题化作01背包问题解决,如果价值为v的物品有x个,则化成x个价值为v的物品;

#include<cstdio>
int main()
{
int n,m,v[105],w[105],f[105];
scanf("%d %d",&m,&n);
for(int i=1; i<=n; i++)
scanf("%d %d",&v[i],&w[i],&num[i]);
int k=n+1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<num[i]; j++)
{
v[k]=v[i];
w[k]=w[i];
k++;
}
}
for(int i=1; i<k; i++)
{
for(int j=m; j>=1; j--)
{
if(w[i]<=j)
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
printf("%d",f[m]);
return 0;
}

  再贴上今天折腾了一晚上的题:http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=2340

把数组改为全局变量竟然就A了,问了老谭,说这是,没有清零的原因,脑瓜子疼!

ACM__01背包,完全背包,多重背包的更多相关文章

  1. HDU 1114 完全背包 HDU 2191 多重背包

    HDU 1114 Piggy-Bank 完全背包问题. 想想我们01背包是逆序遍历是为了保证什么? 保证每件物品只有两种状态,取或者不取.那么正序遍历呢? 这不就正好满足完全背包的条件了吗 means ...

  2. [原]hdu2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (这个只是题目名字) (多重背包)

    本文出自:http://blog.csdn.net/svitter 原题:http://acm.hdu.edu.cn/showproblem.php?pid=2191 题意:多重背包问题.转换成为01 ...

  3. POJ1276 - Cash Machine(多重背包)

    题目大意 给定一个容量为M的背包以及n种物品,每种物品有一个体积和数量,要求你用这些物品尽量的装满背包 题解 就是多重背包~~~~用二进制优化了一下,就是把每种物品的数量cnt拆成由几个数组成,1,2 ...

  4. POJ 1742 Coins(多重背包, 单调队列)

    Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...

  5. HDU1059 二进制拆分优化多重背包

    /*问你能不能将给出的资源平分成两半,那么我们就以一半为背包,运行多重背包模版 但是注意了,由于个数过大,直接运行会超时,所以要用二进制拆分每种的个数*/ #include<stdio.h> ...

  6. 01背包模板、全然背包 and 多重背包(模板)

    转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/ ...

  7. DZY Loves Math II:多重背包dp+组合数

    Description Input 第一行,两个正整数 S 和 q,q 表示询问数量.接下来 q 行,每行一个正整数 n. Output 输出共 q 行,分别为每个询问的答案. Sample Inpu ...

  8. 洛谷P1782 旅行商的背包[多重背包]

    题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...

  9. HDU 2082 找单词 (多重背包)

    题意:假设有x1个字母A, x2个字母B,..... x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,..... 字母Z的价值为26.那么,对于给定的字母,可以找到多少价值<=50的 ...

随机推荐

  1. [UE4]制作缩略图

    一.创建一个专门用来做缩略图的角色CameraCharacter,不需要实体模型. 二.Auto Possess Player设置为“Player 0” 三.重力比例改成0(这样在天上的时候就不会往下 ...

  2. Linux常用命令1-50(持续更新中)

    1:echo $PATH  (打印出PATH变量的值) 不同用户下面的PATH值有可能不一样 echo   有显示打印的意思 $         表示后面的是一个变量的意思 PATH  变量 /usr ...

  3. MySql 索引优化实例

    查询语句 SELECT customer_id,title,content FROM `product_comment` WHERE audit_status=1 AND product_id=199 ...

  4. virtualbox创建虚拟机

    两种方式: 1.使用.vdi硬盘镜像文件 2.使用操作系统新建 方法1: #结束! 方法2:

  5. Google App Engine10年,支持更多你喜欢的编程语言

    2008年4月7日google推出Google App Engine(GAE),时间过得真快,10年过去了,2010年3月google退出中国,一转眼也过去7年了.早在2009年的时候GAE就在中国内 ...

  6. (转)SQL知识_SQL Case when 的使用方法

    原文地址:http://www.cnblogs.com/yazdao/archive/2009/12/09/1620482.html Case具有两种格式.简单Case函数和Case搜索函数. --简 ...

  7. tips:Java的Random类和Random函数

    tips:Java的Random类和Random函数! 随机数是一个很有趣的东西,在java中可以通过下面这2种方法得到: (1)Random类: Random类是java.util.Random这个 ...

  8. Sebastian Ruder : NLP 领域知名博主博士论文面向自然语言处理的神经网络迁移学习

    Sebastian Ruder 博士的答辩 PPT<Neural Transfer Learning for Natural Language Processing>介绍了面向自然语言的迁 ...

  9. 【Selenium-WebDriver自学】Selenium-RC脚本编写(十)

    ==================================================================================================== ...

  10. 剑指Offer(四):重建二叉树

    说明: 1.本系列是根据<剑指Offer>这个系列做的一个小笔记. 2.直接动力是因为师兄师姐找工作很难,而且机械出生的我面试算法更难. 3.刚开始准备刷LeetCode.LintCode ...