HDU_2602 Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 49986    Accepted Submission(s): 20965
Problem Description
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 ?
Input
The 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.
Output
One integer per line representing the maximum of the total value (this number will be less than 231).
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
14
分析:裸01背包。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int maxn = 1000 + 5;int T;
int N, V;
int value[maxn];
int volume[maxn];
int dp[maxn];void input() {scanf("%d%d", &N, &V);for(int i = 0; i < N; ++i) {cin >> value[i];}for(int i = 0; i < N; ++i) {cin >> volume[i];}
}void solve() {memset(dp, 0, sizeof(dp));for(int i = 0; i < N; ++i) {for(int j = V; j >= volume[i]; --j) {dp[j] = max(dp[j - volume[i]] + value[i], dp[j]);}}cout << dp[V] << endl;
}int main() {cin >> T;for(int t = 0; t < T; ++t) {input();solve();}return 0;
}

HDU_2546 饭卡

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 22098    Accepted Submission(s): 7730
Problem Description
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于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背包。涉及贪心策略。首先拿出5元买最贵的菜,那么接下来的背包容量为m-5,物品数量n-1,进行01背包就是了。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int maxn = 1000 + 5;int n, m;
int value[maxn];
int dp[maxn];void input() {for(int i = 0; i < n; ++i) {cin >> value[i];}cin >> m;
}void solve() {if(m < 5) {cout << m << endl;return ;}m -= 5;sort(value, value + n);memset(dp, 0, sizeof(dp));for(int i = 0; i < n - 1; ++i) {for(int j = m; j >= value[i]; --j) {dp[j] = max(dp[j - value[i]] + value[i], dp[j]);}}cout << m + 5 - dp[m] - value[n - 1] << endl;
}int main() {while(cin >> n && n != 0) {input();solve();}return 0;
}

HDU_2955 Robberies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20096    Accepted Submission(s): 7443
Problem Description
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.

Input
The 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 .
Output
For 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
题意:抢匪抢劫银行j的金额是Mj,被抓的概率是Pj。当被抓概率小于P时,认为抢匪是可以逃脱的。那么问题来了,在可逃脱的情况下,抢匪最多能抢多少钱。
分析:01背包。一眼看去是裸01背包,但是数组下标却是浮点数,所以得想办法转化。我们把银行的金额总和当做背包容量,不被抓的概率当做价值,那么转移方程就是:dp[j] = max(dp[j - p[i]] * (1 - m[i]), dp[j])。那么结果也就显而易见了,找到最大的容量V,dp[V] > 1 - P,那么这个V就是结果了。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;#define EPS 0.000000001const int maxn = 100 + 5;int T;
double P;
int N;
int p[maxn];
double m[maxn];
double dp[maxn * maxn];void input() {cin >> P >> N;for(int i = 0; i < N; ++i) {cin >> p[i] >> m[i];}
}void solve() {if(P - 0 < EPS) {cout << "0" << endl;return ;}int V = 0;for(int i = 0; i < N; ++i) {V += p[i];}dp[0] = 1;for(int i = 1; i <= V; ++i) dp[i] = 0;for(int i = 0; i < N; ++i) {for(int j = V; j >= p[i]; --j) {dp[j] = max(dp[j - p[i]] * (1 - m[i]), dp[j]);}}for(int i = V; i >= 0; --i) { if(dp[i] - (1 - P) > EPS) {cout << i << endl;return ;}}
}int main() {cin >> T;for(int t = 0; t < T; ++t) {input();solve();}return 0;
}

HDU_1203 I NEED A OFFER!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 24189    Accepted Submission(s): 9728
Problem Description
Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了。要申请国外的任何大学,你都要交纳一定的申请费用,这可是很惊人的。Speakless没有多少钱,总共只攒了n万美元。他将在m个学校中选择若干的(当然要在他的经济承受范围内)。每个学校都有不同的申请费用a(万美元),并且Speakless估计了他得到这个学校offer的可能性b。不同学校之间是否得到offer不会互相影响。“I NEED A OFFER”,他大叫一声。帮帮这个可怜的人吧,帮助他计算一下,他可以收到至少一份offer的最大概率。(如果Speakless选择了多个学校,得到任意一个学校的offer都可以)。
Input
输入有若干组数据,每组数据的第一行有两个正整数n,m(0<=n<=10000,0<=m<=10000) 
后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。 
输入的最后有两个0。
Output
每组数据都对应一个输出,表示Speakless可能得到至少一份offer的最大概率。用百分数表示,精确到小数点后一位。
Sample Input
10 3 4 0.1 4 0.2 5 0.3 0 0
Sample Output
44.0%

Hint

You should use printf("%%") to print a '%'.

分析:01背包。此题跟HDU_2955很像,求可能得到至少一份工作的最大概率,那么可以考虑反面,得不到工作的最小概率。那么就很容易理解了,转移方程:dp[j] = min(dp[j - a[i]] * (1 - b[i]), dp[j])。结果自然而然就是 1 - dp[n]了。注意这里输出百分数,记得转化。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1203
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int maxn = 10000 + 5;int n, m;
int a[maxn];
double b[maxn];
double dp[maxn];void input() {for(int i = 0; i <m; ++i) {scanf("%d%lf", &a[i], &b[i]);}
}void solve() {dp[0] = 1;for(int i = 1; i <= n; ++i) dp[i] = 1;for(int i = 0; i < m; ++i) {for(int j = n; j >= a[i]; --j) {dp[j] = min(dp[j - a[i]] * (1 - b[i]), dp[j]);//cout << dp[j] << " ";}//cout << endl;}printf("%.1lf%%\n", (1 - dp[n]) * 100);
}int main() {while(scanf("%d%d", &n, &m) != EOF && n+m) {input();solve();}return 0;
}

HDU_1171 Big Event in HDU

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 35145    Accepted Submission(s): 12188
Problem Description
Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
Output
For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
Sample Input
2 10 1 20 1 3 10 1 20 2 30 1 -1
Sample Output
20 10 40 40
题意:把所有电脑分成A,B部分,使得A、B两部分金额尽可能相近,并保证金额 A > B。
分析:01背包。把总价平分一下,较小的一部分当做B背包的容量,那么对B进行01背包即可得到B的最大价值,A的价值也就出来了。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1171
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int maxn = 1000 + 5;
const int maxm = 100 + 5;int N;
int V[maxn];
int M[maxn];
int value[maxn * maxm];
int dp[maxn * maxm];void input() {for(int i = 0; i < N; ++i) {scanf("%d%d", &V[i], &M[i]);}
}void solve() {int sumV = 0, va = 0;for(int i = 0; i < N; ++i) {sumV += V[i] * M[i];for(int j = 0; j < M[i]; ++j) {value[va++] = V[i];}}int minV = sumV / 2;memset(dp, 0, sizeof(dp));for(int i = 0; i < va; ++i) {for(int j = minV; j >= value[i]; --j) {dp[j] = max(dp[j - value[i]] + value[i], dp[j]);}}printf("%d %d\n", sumV - dp[minV], dp[minV]);
}int main() {while(scanf("%d", &N) != EOF && N >= 0) {input();solve();}return 0;
}

HDU_2639 Bone Collector II

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3967    Accepted Submission(s): 2051
Problem Description
The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup" competition,you must have seem this title.If you haven't seen it before,it doesn't matter,I will give you a link:

Here is the link:http://acm.hdu.edu.cn/showproblem.php?pid=2602

Today we are not desiring the maximum value of bones,but the K-th maximum value of the bones.NOTICE that,we considerate two ways that get the same value of bones are the same.That means,it will be a strictly decreasing sequence from the 1st maximum , 2nd maximum .. to the K-th maximum.

If the total number of different values is less than K,just ouput 0.

Input
The 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, K(N <= 100 , V <= 1000 , K <= 30)representing the number of bones and the volume of his bag and the K we need. 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.
Output
One integer per line representing the K-th maximum of the total value (this number will be less than 231).
Sample Input
3 5 10 2 1 2 3 4 5 5 4 3 2 1 5 10 12 1 2 3 4 5 5 4 3 2 1 5 10 16 1 2 3 4 5 5 4 3 2 1
Sample Output
12 2 0
题意:与HDU_2602也就是本博文第一题一样,只不过这次是求第K大优解。
分析:01背包第k优解。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2639

代码清单:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;const int maxn = 100 + 5;
const int maxk = 30 + 5;
const int maxv = 1000 + 5;int T;
int N, V, K;
int value[maxn];
int volume[maxn];int dp[maxv][maxk];
int pre[maxk], now[maxk];void input() {cin >> N >> V >> K;for(int i = 0; i < N; ++i) {cin >> value[i];}for(int i = 0; i < N; ++i) {cin >> volume[i];}
}void solve() {memset(dp, 0, sizeof(dp));pre[K + 1] = now[K + 1] = -1;for(int i = 0; i < N; ++i) {for(int j = V; j >= volume[i]; --j) {for(int k = 1; k <= K; ++k) {pre[k] = dp[j][k];now[k] = dp[j - volume[i]][k] + value[i];}int idxp = 1, idxn = 1, idxk = 1;while(idxk <= K && (idxp <= K || idxn <= K)) {if(pre[idxp] >= now[idxn]) {dp[j][idxk] = pre[idxp++];}else {dp[j][idxk] = now[idxn++];}//Remove duplicate numberif(idxk == 1 || dp[j][idxk] != dp[j][idxk - 1]) { idxk += 1;}}}}cout << dp[V][K] << endl;
}int main() {cin >> T;for(int t = 0; t < T; ++t) {input();solve();}return 0;
}

HDU_01背包系列相关推荐

  1. 背包系列 hdu3449 有依赖背包

    这道题真正困扰了笔者3,4天,冥思苦想几日无果之后,只能去找大牛的解法.结合网上的大牛解法与自己的理解,笔者终于解决了这个坑了,在此小庆幸一下. 原题如下: Consumer Time Limit: ...

  2. HDU_多重背包系列

    HDU_2191 悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/327 ...

  3. leetcode——背包系列

    文章目录 01背包 完全背包问题 零钱兑换(求最少硬币个数) 零钱兑换II(求硬币组合数) 组合总和IV 本来背包问题,比较直观的解释,是用二维的转移方程,但简洁起见,很多地方以及下文的介绍都是用一维 ...

  4. 九十一、动态规划系列 背包问题之混合背包

    @Author:Runsen @Date:2020/09/27 背包系列,是动态规划里一类典型的问题,主要有:01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,有依赖背包和泛化物品等.也 ...

  5. 九十三、动态规划系列之股票问题(下)

    @Author:Runsen 动态规划必须要面对股票系列,背包系列差不多了,那就上吧. 股票买卖这一类的问题,都是给一个输入数组,里面的每个元素表示的是每天的股价,并且你只能持有一支股票(也就是你必须 ...

  6. 九十二、动态规划系列之股票问题(上)

    @Author:Runsen 动态规划必须要面对股票系列,背包系列差不多了,那就上吧. 文章目录 买卖股票的最佳时机(买一次) 买卖股票的最佳时机(买 N 次) 买卖股票的最佳时机(买 2 次) 买卖 ...

  7. 股票系列,动态规划,加油,九月太浪了,十月不许浪

    @Author:Runsen @Date:2020/09/26 悄然间时间来到十月,不禁感慨,过去的这一个月浪的'无知',我其实是一个很没有原则的人,做的很多事情都是随心所欲,骨子里放纵不羁爱自由.可 ...

  8. c++ 多重背包状态转移方程_动态规划入门——详解经典问题零一背包

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周三算法与数据结构专题的第12篇文章,动态规划之零一背包问题. 在之前的文章当中,我们一起探讨了二分.贪心.排序和搜索算法,今天我们来 ...

  9. 背包问题_(DP经典),一,(01背包,填满背包)

    背包系列已更新 一,(01背包,填满背包) 二,(多重背包) 三,(完全背包) 目录 一,01背包(对于一个物品,你要么全拿,要么不拿) 核心dp方程,dp[i][j]=max(dp[i-1][j], ...

最新文章

  1. 【转】jQuery.ajax向后台传递数组问题
  2. java swt 保存文件夹_采用SWT实现系统文件夹的树形结构显示
  3. Java黑皮书课后题第1章:1.12(以千米计的平均速度)假设一个跑步者1小时40分35秒跑了24英里。编写一个程序显示以每小时为多少千米为单位的平均速度值(1英里等于1.6千米)
  4. Ralink5350开发环境搭建
  5. 面向对象的故事~数据底层操作告诉了我们接口,抽象类,继承与多态性的使用~续(TestBase继承ITest是多余的?)...
  6. EduSoho网络课堂通用版
  7. 程序员为什么需要学会Markdown
  8. (已更新)漫画小程序更新修复接口,自动采集资源,漫画源码漫画小程序源码简单即可发布
  9. 厉害了,用Python实现自动扫雷
  10. c语言正弦波程序_怎样很好的恢复一个正弦波信号
  11. 什么是商业智能 (BI) 仪表板?
  12. 【PAT A1094】The Largest Generation
  13. 异地多活 以阿里为例
  14. Linux各种问题解决方案
  15. 与CPU相关的计算题
  16. 大数据专业就业岗位有哪些?
  17. 2021第七届美亚杯中国电子数据取证大赛详解write up
  18. 程序员用Python赚外快的具体指南!找点轻松的活增加收入
  19. MySQL 开启大页内存
  20. 戴尔灵越新增固态硬盘不识别问题解决

热门文章

  1. 争议中的云算力市场 |链捕手
  2. Tomcat是什么。Tomcat入门介绍
  3. cpu上干硅脂怎么清理_cpu上面硅胶怎么清洗
  4. opencv+face_recognition+python实现换脸(face swap)操作(3)——基于普氏分析法(Procrustes Analysis)的代码实现
  5. 时间同步——TSN(Time Sensitive Network-时间敏感网络)协议802.1AS介绍
  6. 笔记36 笨办法学python练习43面向对象OOP的文字理解(一)
  7. 电子计算机原理讲义,最新计算机原理讲义资料.doc
  8. Linux的数字签名,Ubuntu系统下-加密和数字签名Email
  9. 服务器组装风扇,服务器配件之风扇篇
  10. 文献—Emergent simplicity in microbial community assembly--论文全过程详细阅读整理与翻译