背包专题(持续更新)

POJ 3624 Charm Bracelet

题目链接:http://poj.org/problem?id=3624

Description

Bessie has gone to the mall‘s jewelry store and spies a charm bracelet. Of course, she‘d like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) available charms. Each charm i in the supplied list has a weight Wi (1 ≤ Wi ≤ 400), a ‘desirability‘ factor Di (1 ≤ Di ≤ 100), and can be used at most once. Bessie can only support a charm bracelet whose weight is no more than M (1 ≤ M ≤ 12,880).

Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.

Input

* Line 1: Two space-separated integers: N and M
* Lines 2..N+1: Line i+1 describes charm i with two space-separated integers: Wi and Di

Output

* Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints

Sample Input

4 6
1 4
2 6
3 12
2 7

Sample Output

23

题解:01背包

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 int dp[200005];
 8 int main()
 9 {
10     int n,m;
11     while(cin>>n>>m){
12         int x,y;
13         memset(dp,0,sizeof(dp));
14         for(int i=0;i<n;i++){
15             cin>>x>>y;
16             for(int j=m;j>=x;j--){
17                 dp[j]=max(dp[j],dp[j-x]+y);
18             }
19         }
20         cout<<dp[m]<<endl;
21     }
22     return 0;
23 }

HDU 2602 Bone Collecter

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave … 
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ? 

InputThe first line contain a integer T , the number of cases. 
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.OutputOne integer per line representing the maximum of the total value (this number will be less than 2 31).Sample Input

1
5 10
1 2 3 4 5
5 4 3 2 1

Sample Output

14

题解:01背包

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 int dp[200005];
 8 int a[1001];
 9 int b[1001];
10 int main()
11 {
12     int n,v,t;
13     cin>>t;
14     while(t--){
15         cin>>n>>v;
16         memset(dp,0,sizeof(dp));
17         for(int i=0;i<n;i++)
18             cin>>a[i];
19         for(int i=0;i<n;i++)
20             cin>>b[i];
21         for(int i=0;i<n;i++){
22             for(int j=v;j>=b[i];j--){
23                 dp[j]=max(dp[j],dp[j-b[i]]+a[i]);
24             }
25         }
26         cout<<dp[v]<<endl;
27     }
28     return 0;
29 }

HDU 2546 饭卡

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546

电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。 
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。

Input多组数据。对于每组数据: 
第一行为正整数n,表示菜的数量。n<=1000。 
第二行包括n个正整数,表示每种菜的价格。价格不超过50。 
第三行包括一个正整数m,表示卡上的余额。m<=1000。

n=0表示数据结束。 
Output对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。Sample Input

1
50
5
10
1 2 3 2 1 1 2 3 2 1
50
0

Sample Output

-45
32

题解:01背包变形
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 int dp[1010];
 7 int val[1010];
 8 int main()
 9 {
10     int n,i,j,m;
11     while(cin>>n&&n){
12         memset(dp,0,sizeof(dp));
13         memset(val,0,sizeof(val));
14         for(int i=0;i<n;i++)
15             cin>>val[i];
16         cin>>m;
17         if(m<5) {
18             cout<<m<<endl;
19             continue;
20         }
21         sort(val,val+n);
22         int maxn=val[n-1];
23         m-=5;
24         if(m>=val[0]){
25             for(int i=0;i<n-1;++i){
26                 for(j=m;j>=val[i];--j){
27                     dp[j]=max(dp[j],dp[j-val[i]]+val[i]);
28                 }
29             }
30         }
31         cout<<m+5-dp[m]-maxn<<endl;
32     }
33     return 0;
34 }

HDU 2955 Robberies

The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university.


For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.

His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.

InputThe first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj . 
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .OutputFor each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

Notes and Constraints 
0 < T <= 100 
0.0 <= P <= 1.0 
0 < N <= 100 
0 < Mj <= 100 
0.0 <= Pj <= 1.0 
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.Sample Input

3
0.04 3
1 0.02
2 0.03
3 0.05
0.06 3
2 0.03
2 0.03
3 0.05
0.10 3
1 0.03
2 0.02
3 0.05

Sample Output

2
4
6

题解:

最重要的是找动态转移方程,可以将所用银行里的钱看作背包容量,每一家银行的钱看作重量,

不被抓到的概率看作价值,则转移方程为:dp[ j ]=max( dp[ j ] , dp[ j - bag[ i ].v]*( 1- bag[ i ].p ) );

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 double dp[10010];
 8 struct Bag
 9 {
10     int v;
11     double p;
12 }bag[10010];
13 int main()
14 {
15     int n,t;
16     double p;
17     cin>>t;
18     while(t--){
19         cin>>p>>n;
20         int sum=0;
21         for(int i=0;i<n;i++){
22             cin>>bag[i].v>>bag[i].p;
23             sum+=bag[i].v;
24         }
25         memset(dp,0,sizeof(dp));
26         dp[0]=1;
27         for(int i=0;i<n;i++){
28             for(int j=sum;j>=bag[i].v;j--){
29                 dp[j]=max(dp[j],dp[j-bag[i].v]*(1-bag[i].p));
30             }
31         }
32         for(int i=sum;i>=0;i--){
33             if(dp[i]>1-p){
34                 cout<<i<<endl;
35                 break;
36             }
37         }
38     }
39     return 0;
40 }

UVA 562 Dividing coins

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=503

题解:最重要的是找动态转移方程,可以将所用银行里的钱看作背包容量,每一家银行的钱看作重量,

不被抓到的概率看作价值,则转移方程为:dp[ j ]=max( dp[ j ] , dp[ j - bag[ i ].v]*( 1- bag[ i ].p ) );
*/

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 double dp[10010];
 8 struct Bag
 9 {
10     int v;
11     double p;
12 }bag[10010];
13 int main()
14 {
15     int n,t;
16     double p;
17     cin>>t;
18     while(t--){
19         cin>>p>>n;
20         int sum=0;
21         for(int i=0;i<n;i++){
22             cin>>bag[i].v>>bag[i].p;
23             sum+=bag[i].v;
24         }
25         memset(dp,0,sizeof(dp));
26         dp[0]=1;
27         for(int i=0;i<n;i++){
28             for(int j=sum;j>=bag[i].v;j--){
29                 dp[j]=max(dp[j],dp[j-bag[i].v]*(1-bag[i].p));
30             }
31         }
32         for(int i=sum;i>=0;i--){
33             if(dp[i]>1-p){
34                 cout<<i<<endl;
35                 break;
36             }
37         }
38     }
39     return 0;
40 }
51 Nod 1085 背包问题题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1085

在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。


Input

第1行,2个整数,N和W中间用空格隔开。N为物品的数量,W为背包的容量。(1 <= N <= 100,1 <= W <= 10000)
第2 - N + 1行,每行2个整数,Wi和Pi,分别是物品的体积和物品的价值。(1 <= Wi, Pi <= 10000)

Output

输出可以容纳的最大价值。

Input示例

3 6
2 5
3 8
4 9

Output示例

14

题解:01背包模板

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 int dp[100005];
 6 int main()
 7 {
 8     int n,w,x,y;
 9     scanf("%d%d",&n,&w);
10     memset(dp,0,sizeof(dp));
11     for(int i=1;i<=n;i++){
12         scanf("%d%d",&x,&y);
13         for(int j=w;j>=x;j--){
14             dp[j]=max(dp[j],dp[j-x]+y);
15         }
16     }
17     cout<<dp[w]<<endl;
18     return 0;
19 }

51Nod  1086 背包问题 V2

有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。

Input

第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)
第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)

Output

输出可以容纳的最大价值。

Input示例

3 6
2 2 5
3 3 8
1 4 1

Output示例

9

题解:多重背包 
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 int dp[500005];
 6 int main()
 7 {
 8     int n,m,w,c,p,k,flag;
 9     scanf("%d%d",&n,&m);
10     memset(dp,0,sizeof(dp));
11     for(int i=1;i<=n;i++){
12         scanf("%d%d%d",&w,&p,&c);
13         for(k=1,flag=1; ;k*=2){
14             if(k*2>=c){
15                 k=c-k+1;
16                 flag=0;
17             }
18         for(int j=m;j >= k*w;j--){
19             dp[j]=max(dp[j],dp[j-k*w]+k*p);
20
21         }
22         if(flag==0) break;
23         }
24     }
25     cout<<dp[m]<<endl;
26     return 0;
27 }
				
时间: 2024-11-29 11:08:10

背包专题(持续更新)的相关文章

个人专题训练——背包dp(持续更新中)

A - Proud Merchants   HDU - 3466(带限制的01背包) 题意: 给你m元,去买大米,每袋大米给你p,q,v 当你手中的钱 >= q时,才能买价格为p的这袋大米,它的价值是v,求最大价值. 01背包的转移方程根据题意很容易写出来,但是会有问题. for (int i = 1; i <= n; ++i) for (int j = m; j >= q[i]; --j) dp[j] = max(dp[j], dp[j - p[i]] + v[i]);考虑到了可能存在

功能使用来源(持续更新)

从开始编写项目到现在,用过好多插件,但是有的时候用过后,时间一长就会忘记,这里我整理一下,以防忘记,我会持续更新的!!! 图表类: Jfreechart 适合java和jsp使用 界面差,不易维护,说白了,显示的就是一张图片: highcharts web使用,js插件,界面绚丽,官网有好多demo(当时没有找到这个,于是用的jfreechart...): echarts 近期找到的,百度制作,叫百度图说,我很看好这个,下次如有需要制作图表的时候,我一定用这个!!!这个也有好多的demo,我看了

自己总结的 iOS ,Mac 开源项目以及库,知识点------持续更新

自己在 git  上看到一个非常好的总结的东西,但是呢, fork  了几次,就是 fork  不到我的 git 上,干脆复制进去,但是,也是认真去每一个每一个去认真看了,并且也是补充了一些,感觉非常棒,所以好东西要分享,为啥用 CN 博客,有个好处,可以随时修改,可以持续更新,不用每次都要再发表,感觉这样棒棒的 我们 自己总结的iOS.mac开源项目及库,持续更新.... github排名 https://github.com/trending,github搜索:https://github.

2017年上半年软考报名时间汇总(持续更新)

全国2017年上半年软考报名时间汇总(持续更新) 关注报名时间:各省报名开始时间.结束时间不一. 关注报考科目:部分科目一年只考核一次. 关注考试时间:上半年时间为5月20日,及时开始应试准备. 最新 | 2017年上半年软考考试时间和主要考试科目 序号 地区 开始时间 结束时间 1 湖北 1月23日 4月15日 2 海南 2月13日 3月13日 3 四川 2月15日 3月15日 4 青海 2月27日 3月12日 5 浙江 3月1日 4月10日 6 山东 3月14日 3月23日 7 湖南 3月2

转-推荐的几个开发常用在线工具,可以提升开发效率(持续更新)

http://blog.csdn.net/kroclin/article/details/40634975 相信开发中每个人手头上面都有那么几个工具可以让你每天洋洋得意的开发软件,而这里我就将我觉得还挺不错的几款在线工具分享出来,仁者见仁啦,喜欢就拿走.还会持续更新,以后有新的我都贴上来. 1.MD5解密:http://www.cmd5.com/ 2.MD5加密:http://md5jiami.51240.com/ 3.json在线解析工具:http://json.parser.online.f

iOS开发系列文章(持续更新……)

iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大家交流,新建一个iOS技术交流群,欢迎大家加入:64555322 C语言 IOS开发系列--C语言之基础知识 IOS开发系列--C语言之数组和字符串 IOS开发系列--C语言之指针 IOS开发系列--C语言之预处理 IOS开发系列--C语言之存储方式和作用域 IOS开发系列--C语言之构造类型 Ob

linux学习资料持续更新中

一.LINUX基础教程 1.老男孩系列免费视频: 1) linux高薪入门实战视频教程(第二部)老男孩linux教程 http://edu.51cto.com/course/course_id-1035-page-1.html 2) 跟着老男孩从0开始一步步实战深入学习linux运维(三) http://edu.51cto.com/lesson/id-11909.html linux学习资料持续更新中,布布扣,bubuko.com

Linux系统各发行版镜像下载(持续更新)

Linux系统各发行版镜像下载(持续更新) http://www.linuxidc.com/Linux/2007-09/7399.htm Linux系统各发行版镜像下载(2014年10月更新),如果直接下载不了,请使用迅雷下载.并且注意,我的下载地址,在  迅雷 里才起作用. 包括Ubuntu,Fedora,SUSE,Red Hat Enterprise Linux,CentOS等. 中国大陆开源镜像站汇总 1.企业贡献: 搜狐开源镜像站:http://mirrors.sohu.com/网易开源

MongoDB学习——持续更新

參考MongoDB权威指南,学习阶段.大家多多交流问题.持续更新本文 MongoDB的长处 MongoDB具有丰富的数据模型,是面向文档的数据库. easy扩展.能够在多台server之间切割数据. 开发人员仅仅需专注于编写应用.假设须要更大的数据.仅仅需在集群中加入新机器,然后让数据库来处理剩下的事情. 具有丰富的功能,比方索引,存储JavaScript,聚合,固定集合.文件存储. 不支持联接(join)和复杂的多行事物. 卓越的性能是MongoDB的主要目标,默认的存储引擎使用了内存映射文件

C#、Java中的一些小功能点总结(持续更新......)

前言:在项目中,有时候一些小的功能点,总是容易让人忽略,但是这些功能加在项目中往往十分的有用,因此笔者在这里总结项目中遇到的一些实用的小功能点,以备用,并持续更新...... 1.禁用DataGridView表头的排序功能 1 /// <summary> 2 /// 禁止点击列表头进行排序 3 /// </summary> 4 /// <param name="dgv">当前DataGridView控件</param> 5 private