经典背包系列问题

背包问题I
 

试题描述

有一个背包容积为 V 和 n 个物品,并给出每个物品有一个体积。要求从 n 个物品中,任取若干个装入背包内,使背包的剩余空间为最小。


输入

第一行两个正整数 V 和 n,分别表示背包的容积和待装物品的个数;第二行包括 n 个正整数,表示 n 个物品的体积,两两之间有一个空格分隔。

输出

一个数,表示背包中剩余空间的最小值

输入示例

24 6
8 3 12 7 9 7

输出示例

0

其他说明

数据范围:0<V≤20000,0<n≤30

背包问题II
 

试题描述

仍然是背包问题……典型0-1背包!题曰:今有n个物品,第i个体积为V[i],价值为W[i],背包的容积为C。求在体积不超容积的前提下,背包中可装物品价值的最大值。


输入

第一行:两个整数 n 和 C ;
第二行~第n+1行:每行两个整数Vi与Wi,有一个空格分隔。

输出

一个数,表示背包中能得到物品价值的最大值。 

输入示例

2 10
1 1
2 2

输出示例

3

 1 #include<iostream>
 2 using namespace std;
 3 int a[10001]={},b[10001]={},temp1,temp2;//b[i]为上一行,a[i]为这行
 4 int main()
 5 {
 6     int n,c;
 7     int i,j;
 8     cin>>n>>c;
 9     for(i=1;i<=n;i++)
10     {
11         cin>>temp1>>temp2;//输入
12         for(j=1;j<=c;j++)//DP
13         {
14             if(j<temp1) a[j]=b[j];
15             else{a[j]=max(b[j-temp1]+temp2,b[j]);}
16         }
17         for(j=1;j<=c;j++)b[j]=a[j];
18     }
19     cout<<b[c];
20 }

背包问题III
 

试题描述

背包问题,古之经典。题曰:今有n类物品无数,第i种体积为V[i],价值为W[i],背包的体积为C。求在体积不超容积的前提下,背包中物品价值最大值。


输入

第一行:两个整数 n 和 C ;
第二行~第n+1行:每行两个整数Vi与Wi,有一个空格分隔。

输出

一个数,表示背包中能得到物品价值的最大值。 

输入示例

4 1000
1 1000
2 1231
3 1232
4 1010

输出示例

1000000

其他说明

数据范围:1<=n<=100 1<=Vi,Wi<=100;1<=C<=10000; 

 1 #include<iostream>
 2 using namespace std;
 3 int a[2][10001]={},temp1,temp2;
 4 int main()
 5 {
 6     int n,c;
 7     int i,j;
 8     cin>>n>>c;
 9     for(i=1;i<=n;i++)
10     {
11         cin>>temp1>>temp2;
12         for(j=1;j<=c;j++)
13         {
14             if(j<temp1) a[1][j]=a[0][j];
15             else{a[1][j]=max(a[1][j-temp1]+temp2,a[0][j]);}
16         }
17         for(j=1;j<=c;j++) a[0][j]=a[1][j];
18     }
19     cout<<a[1][c];
20 }

背包问题Ⅳ
 

试题描述

有n个重量和价值分别为Wi和Vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。


输入

三行,第一行包含两个正整数n和W,第二行包含n个正整数依次表示i个物品各自的重量,第三行包含n个正整数依次表示i个物品各自的价值。同一行的数两两之间有一个空格分隔。

输出

一个数,表示价值总和的最大值。

输入示例

4 5
2 1 3 2
3 2 4 2

输出示例

7

其他说明

数据范围:1<=n,Vi<=100,1<=W<=10^9,1<=Wi<=10^7.

 1 #include<iostream>
 2 using namespace std;
 3 int a[2][10005]={},t1[101],t2[101];
 4 int main()
 5 {
 6     int n,w;
 7     cin>>n>>w;
 8     for(int i=1;i<=n;i++) scanf("%d",&t1[i]);
 9     for(int i=1;i<=n;i++) scanf("%d",&t2[i]);
10     for(int i=1;i<=n;i++)
11     {
12         for(int j=10001;j>=1;j--)
13         {
14             a[1][j]=a[0][j];
15             if(j<t2[i]) break;
16             if(j-t2[i]==0)
17             {
18                 if(a[1][j]==0) a[1][j]=t1[i];
19                 else a[1][j]=min(a[1][j],t1[i]);
20             }
21             else if(a[0][j-t2[i]]!=0)
22             {
23                 if(!a[1][j]) a[1][j]=a[0][j-t2[i]]+t1[i];
24                 else a[1][j]=min(a[1][j],a[0][j-t2[i]]+t1[i]);
25             }
26         }
27         for(int j=1;j<=10001;j++) a[0][j]=a[1][j];
28     }
29     int ans=0;
30     for(int i=1;i<=10001;i++) if(a[1][i]<=w&&a[1][i]!=0) ans=i;
31     cout<<ans;
32 }

时间: 2024-11-03 21:02:15

经典背包系列问题的相关文章

时序图与状态图(Rose) - Windows XP经典软件系列

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处! 二叉排序树是一种动态排序的数据结构,支持插入.删除.查找等操作,且平均时间复杂度为O(log(N)),但是普通二叉排序树不能保证树退化为一颗分支的情况,此时最坏情况下的时间复杂度为O(N).此时,平衡二叉树的产生了.平衡二叉树是一种动态调整平衡的数据结构,但理想的平衡二叉树很难,于是人们使用AVL.红黑树.Treap.伸展树等来替代平衡二叉树,这些数据

类图(Rose) - Windows XP经典软件系列

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处! 二叉排序树是一种动态排序的数据结构,支持插入.删除.查找等操作,且平均时间复杂度为O(log(N)),但是普通二叉排序树不能保证树退化为一颗分支的情况,此时最坏情况下的时间复杂度为O(N).此时,平衡二叉树的产生了.平衡二叉树是一种动态调整平衡的数据结构,但理想的平衡二叉树很难,于是人们使用AVL.红黑树.Treap.伸展树等来替代平衡二叉树,这些数据

【白话经典算法系列之十七】 数组中只出现一次的数 其他三次

本文地址:http://blog.csdn.net/morewindows/article/details/12684497转载请标明出处,谢谢. 欢迎关注微博:http://weibo.com/MoreWindows 首先看看题目要求: 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次.请给出最快的方法找到x. 这个题目非常有意思,在本人博客中有<位操作基础篇之位操作全面总结>这篇文章介绍了使用位操作的异或来解决——数组中其他数字出现二次,而x出现一次,找出x.有<

三白话经典算法系列 Shell排序实现

山是包插入的精髓排序排序.这种方法,也被称为窄增量排序,因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序. 由于直接插入排序在元素基本有序的情况下(接近最好情况),效率是非常高的,因此希尔排序在时间效率上比前两种方法有较大提高. 以n=10的一个数组49, 38, 65, 97

白话经典算法系列之四 直接选择排序及交换二个数据的正确实现

分类: 白话经典算法系列 2011-08-09 11:15 16682人阅读 评论(29) 收藏 举报 算法面试c 直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是直接播放排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后. 设数组为a[0…n-1]. 1.      初始时,数组全为无序区为a[0..n-1].令i=0 2.      在无序区a[i…n-1]中选取一个最小的元素,将其与a[i]交

白话经典算法系列之七 堆与堆排序

堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)不论什么一个子节点的键值. 2.每一个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于不论什么一个子节点的键值时为最大堆.当父结点的键值总是小于或等于不论什么一个子节点的键值时为最小堆.下图展示一个最小堆

【从零学习经典算法系列】分治策略实例——二分查找

1.二分查找算法简介 二分查找算法是一种在有序数组中查找某一特定元素的搜索算法.搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组 为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半.折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn). 二分查找的优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且

转载 CSS3 经典教程系列:CSS3 盒阴影(box-shadow)详解

目标大纲 文章转载 CSS3 经典教程系列:CSS3 盒阴影(box-shadow)详解 IE中CSS-filter滤镜小知识大全

白话经典算法系列之三 希尔排序的实现

分类: 白话经典算法系列 2011-08-08 11:41 47406人阅读 评论(46) 收藏 举报 算法shell优化c 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的 元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为 直接插入排序在元素基本有序的情况下(接近最好情