01背包

01背包

问题的引入: 01背包简化版

        现有N个物品,每个物品重量为W,这些物品能否使载重量为S的背包装满(即重量和正好为S)?如果不能正好装满,那么背包最多能装多少重量的物品?
【输入文件】
         第一行两个正整数N(0 < N < 1000)和S(0 < S < 10000)表示物品的个数和背包的容量,第二行N个整数列出这N个物品各自的重量。
【输出文件】
         单独一行,表示背包最大的载重量。
【输入样例】
         6 24
         8 3 12 7 9 7
【输出样例】
         24

【分析】
         针对这一问题我们以物品的个数分阶段,设计一个状态dp[i]表示载重量为i的背包可否装满,显然dp[i]的基类型是bool。 
        决策是什么呢?
         当要装第i个物品时,如果前i-1个物品可以使载重为 k的背包装满,那么载重为k+w[i]的背包就可以装满。于是对于一个dp[j]来说,只要dp[j-w[i]]是true(表示可装满)那dp[j]就可以装满。
         但要注意:针对每一个物品枚举背包的载重量时如果这样正向的推导会使同一个物品用好几次,因为k+w[i]可装满那么k+w[i]+w[i]就可装满,但实际上是装不满的,因为物品只有一个。解决这个问题很简单,只要逆向推导就OK了。
         这样划分阶段,设计状态,满足无后效性和么?
         显然对于每一个物品(阶段)都是独立的,物品的顺序并不影响求解,因为装物品的次序不限。而对于dp[j]只考虑dp[j-w[i]]而不考虑后面的,所以满足无后效性。
         有了上面的分析不难写出状态转移方程:
        

dp[j] = dp[j-w[i]]       {dp[j-w[i]] = true}

参考程序:
#include <iostream>
#include <cstdio>
using namespace std;
int w[1005], dp[1005];
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++) scanf("%d", &w[i]);
    dp[0]=1;
    for (int i = 1; i <= n; i ++) 
        for (int j = m; j >= w[i]; j --)
		if (dp[j-w[i]]==1) dp[j] = 1;
    for (int i = m; i >=0; i --)
        if (dp[i] == 1){ printf("%d\n", i); break; }
    return 0;    
}

【例题1】 装箱问题 

        有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30=,每个物品有一个体积(正整数)。
         要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
【输入文件】
         第一行一个正整数V表示箱子的容量,第二行一个正整数N表示物品个数,接下来N行列出这N个物品各自的体积。
【输出文件】
         单独一行,表示箱子最小的剩余空间。
【输入样例】
         24
         6
         8
         3
         12
         7
         9
         7
【输出样例】
         0

【问题分析】
         本题是经典的0/1背包问题,并且是0/1背包的简化版,把箱子看做背包,容量看做载重量,体积看做重量,剩余空间最小也就是尽量装满背包。于是这个问题便成了:
         有一个栽重量为V的背包,有N个物品,尽量多装物品,使背包尽量的重。
         设计一个状态opt[i]表示重量i可否构成。
         状态转移方程:opt[j]:=opt[j-w[1]] {opt[j-w[i]]=true}
         最终的解就是v-x(x<=n 且opt[x]=true 且 opt[x+1..n]=false)。

参考程序:
#include <iostream>
#include <cstdio>
using namespace std;
int w[1005], dp[1005];
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++) scanf("%d", &w[i]);
    dp[0]=1;
    for (int i = 1; i <= n; i ++) 
        for (int j = m; j >= w[i]; j --)
	    if (dp[j-w[i]]==1) dp[j] = 1;
    for (int i = m; i >=0; i --)
        if (dp[i] == 1){ printf("%d\n", m-i); break; }
    return 0;    
}

【例题2】 砝码称重

        设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),用他们能称出的重量的种类数。
【输入文件】
         a1 a2 a3 a4 a5 a6
         (表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个,中间有空格)。
【输出文件】
         N
         (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值