hdu 01背包汇总(1171+2546+1864+2955。。。
1171
题意比较简单,这道题比较特别的地方是01背包中,每个物体有一个价值有一个重量,比较价值最大,重量受限,这道题是价值受限情况下最大,也就值把01背包中的重量也改成价值。
//Problem : 1171 ( Big Event in HDU ) Judge Status : Accepted #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std; int v[6000], dp[5000 * 50 + 10]; int main() {
//freopen("in.txt", "r", stdin);
int n;
int sum;
while (scanf("%d", &n) != EOF && n >= 0) {
memset(dp, 0, sizeof(dp));
int a, b;
sum = 0;
int idx = 0;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &a, &b);
sum += a * b;
for (int j = 0; j < b; j++) {
v[++idx] = a;
}
}
for (int i = 1; i <= idx; i++)
for (int j = sum / 2; j >= v[i]; j--)
dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
printf("%d %d\n", sum - dp[sum / 2], dp[sum / 2]);
}
return 0;
}
2546
和上面一样,没有重量,只有价值。
如果卡上不足5元,输出原值。如果大于5元,就在m-5范围内花最多的钱(留下最贵的菜),然后用剩下的钱减去最贵的菜。
代码
//Problem : 2546 ( 饭卡 ) Judge Status : Accepted
#include <iostream>
#include <algorithm>
using namespace std; int v[1005];
int dp[1005]; int main()
{
int n, m;
while (cin >> n && n) {
memset(dp, 0, sizeof(dp)); //又忘记初始化然后wa了一发。。。
for (int i = 1; i <= n; ++i) {
cin >> v[i];
}
cin >> m;
if (m < 5) {
printf("%d\n", m);
continue;
}
sort(v + 1, v + n + 1);
for (int i = 1; i < n; ++i) {
for (int j = m - 5; j >= v[i]; j--)
dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
}
printf("%d\n", m - dp[m - 5] - v[n]);
} return 0;
}
2602
水题,不写了。基本01背包。
1864
题意很简单,做法也很简单,全部*100变成整数然后01背包。
一处(int)(q*100)不小心写成了(int)q*100调试了好久才找到,蠢蠢蠢= =
//Problem : 1864 ( 最大报销额 ) Judge Status : Accepted /**< hdu 1864 */
#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; double pri[35]; //合法发票的价格
int pric[35];
int dp[35 * 1000 * 100]; int main()
{
double q;
int n, m;
double pri_a, pri_b, pri_c;
while (scanf("%lf%d", &q, &n) != EOF && n) {
int idx = 0;
for (int i = 0; i < n; ++i) {
cin >> m;
pri_a = pri_b = pri_c = 0;
char ch;
double price;
int ok = 1;
for (int j = 0; j < m; ++j) {
scanf(" %c:%lf", &ch, &price);
switch(ch) {
case 'A' :
pri_a += price;
break;
case 'B' :
pri_b += price;
break;
case 'C' :
pri_c += price;
break;
default: ok = 0;
}
}
double sum = pri_a + pri_b + pri_c;
//printf("a=%f,b=%f,c=%f,sum=%f\n", pri_a, pri_b, pri_c, sum);
if (!(pri_a > 600 || pri_b > 600 || pri_c > 600 || sum > 1000) && ok) pri[++idx] = sum;
} //end for 求出pri[] for (int i = 1; i <= idx; i++) {
pric[i] = (int)(pri[i] * 100);
} memset(dp, 0, sizeof(dp));
for (int i = 1; i <= idx; ++i) {
for (int j = (int)(q * 100); j >= pric[i]; --j) {
dp[j] = max( dp[j], dp[j - pric[i]] + pric[i]);
}
}
printf("%.2f\n", dp[(int)(q * 100)] / 100.00);
}
return 0;
}
这题也可以换一种方法做,用张数当背包。
我们平时的背包都是质量,当数据过大,或像这个一样是实数,可以转换思维,用价值当背包等。
//Problem : 1864 ( 最大报销额 ) Judge Status : Accepted #include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; double pri[35];
double dp[35]; int main()
{
double q;
int n, m;
double pri_a, pri_b, pri_c;
while (scanf("%lf%d", &q, &n) != EOF && n) {
int idx = 0;
for (int i = 0; i < n; ++i) {
cin >> m;
pri_a = pri_b = pri_c = 0;
char ch;
double price;
int ok = 1;
for (int j = 0; j < m; ++j) {
scanf(" %c:%lf", &ch, &price);
switch(ch) {
case 'A' :
pri_a += price;
break;
case 'B' :
pri_b += price;
break;
case 'C' :
pri_c += price;
break;
default: ok = 0;
}
}
double sum = pri_a + pri_b + pri_c;
//printf("a=%f,b=%f,c=%f,sum=%f\n", pri_a, pri_b, pri_c, sum);
if (!(pri_a > 600 || pri_b > 600 || pri_c > 600 || sum > 1000) && ok) pri[++idx] = sum;
} //end for 求出pri[] for (int i = 0; i <= idx; i++) {
dp[i] = 0.0;
} for (int i = 1; i <= idx; ++i) {
for (int j = idx; j >= 1; --j) {
if (dp[j - 1] + pri[i] <= q)
dp[j] = max(dp[j], dp[j - 1] + pri[i]);
}
}
double ans = 0;
for (int i = 1; i <= idx; ++i)
if (ans < dp[i]) ans = dp[i];
printf("%.2f\n", ans);
}
return 0;
}
2955
又是一道不是整数的题,可以看出这道题不能像上一道那样简答的通过x100完成,因为精度不够。
可以把概率当背包,这题还有一处不同就是不是加,概率是乘
//Problem : 2955 ( Robberies ) Judge Status : Accepted #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; double P[105]; //每一家银行不被抓的概率
int M[105]; //每一家银行偷到的钱...
double dp[10005]; int main()
{
int t;
cin >> t;
while (t--) {
int n;
int sum = 0;
double p;
cin >> p >> n;
for (int i = 1; i <= n; ++i) {
cin >> M[i] >> P[i];
P[i] = 1 - P[i];
sum += M[i];
}
memset(dp, 0, sizeof(dp));//又特么忘了这句wa一发。。。
dp[0] = 1; //不偷时不被抓概率是1
for (int i = 1; i <= n; ++i) {
for (int j = sum; j >= M[i]; --j) {
dp[j] = max(dp[j], dp[j - M[i]] * P[i]); //不被抓的概率最大
}
}
for (int i = sum; i >= 0; --i)
if (dp[i] > 1 - p) {
printf("%d\n", i);
break;
}
}
return 0;
}
hdu 01背包汇总(1171+2546+1864+2955。。。的更多相关文章
- 1171 Big Event in HDU 01背包
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意:把商品分成两半,如不能均分,尽可能的让两个数相接近.输出结果:两个数字a,b且a>=b. ...
- HDU 1171 Big Event in HDU(01背包)
题目地址:HDU 1171 还是水题. . 普通的01背包.注意数组要开大点啊. ... 代码例如以下: #include <iostream> #include <cstdio&g ...
- hdu 1171 Big Event in HDU (01背包, 母函数)
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU 1171 Big Event in HDU(01背包)
题目链接 题意:给出n个物品的价值v,每个物品有m个,设总价值为sum,求a,b.a+b=sum,且a尽可能接近b,a>=b. 题解:01背包. #include <bits/stdc++ ...
- hdu 0-1背包
题目地址http://acm.hdu.edu.cn/showproblem.php?pid=2602 #include <stdio.h> #include <string.h> ...
- Big Event in HDU(01背包)
/* 题意: 输入一个数n代表有n种物品, 接下来输入物品的价值和物品的个数: 然后将这些物品分成A B 两份,使A B的价值尽可能相等也就是尽量分的公平一些,如果无法使A B相等,那么就使A多一些: ...
- HUD 1171 Big Event in HDU(01背包)
Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest depa ...
- hdu1171Big Event in HDU(01背包)
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- hdu 2955 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=2955 如果认为:1-P是背包的容量,n是物品的个数,sum是所有物品的总价值,条件就是装入背包的物品的体积和不能 ...
随机推荐
- Mac操作系统常用快捷键
复制:cmd+c 粘贴:cmd+v 剪切:先cmd+c,再cmd+opt+v 显示桌面:cmd+F3 切换输入法:cmd+space 打开Spotlight:ctrl+s ...
- python 读取机器信息
本人最近新学python ,用到关于机器的相关信息,经过一番研究,从网上查找资料,经过测试,总结了一下相关的方法. # -*- coding: UTF8 -*- import os import wi ...
- ctf总结
在过去的一个学期中,草人在西普学院还有一些其他安全夺旗网站上刷了一些题,草人我是菜鸟一个,刚开始很是苦恼,所以经历过以后希望将之分享给一起学习安全的同学,目的呢是希望以后学习的人能尽快理清学习思路,进 ...
- iOS 中SQLite数据库操作
在iOS中实现SQLite数据库的操作:1.导入框架(libsqlite3.0.tbd) 2.导入头文件<sqlite3.h> 3.实现数据的增删改查 实现简单 SQLite数据库操作 的 ...
- linux awk命令详解(转)
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编 ...
- Android USB Host 与 HID 之通讯方法
Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两个方法,要实现真正的通 ...
- RxJava开发精要7 – Schedulers-解决Android主线程问题
原文出自<RxJava Essentials> 原文作者 : Ivan Morgillo 译文出自 : 开发技术前线 www.devtf.cn 转载声明: 本译文已授权开发者头条享有独家转 ...
- 11个强大的Visual Studio调试小技巧(转)
简介 调试是软件开发周期中很重要的一部分.它具有挑战性,同时也很让人疑惑和烦恼.总的来说,对于稍大一点的程序,调试是不可避免的.最近几年,调试工具的发展让很多调试任务变的越来越简单和省时. 这篇文章总 ...
- 【HDOJ】4057 Rescue the Rabbit
挺有意思的一道题目,解法是AC自动机+DP.AC自动机建立fail指针时,一定要注意结点的属性也需要传递.AC自动机结合了trie和kmp的优点.需要注意的是,每个模式串仅计算一次,否则这题很难解. ...
- Form表单中的三种查询方法
1.使用:parameter.G_query_find参数: IF (NAME_IN('PO_HEADERS.PO_HEADER_ID') IS NOT NULL) THEN :paramete ...