DP:Cow Exhibition(POJ 2184)(二维问题转01背包)
题目大意:Bessie要选一些牛参加展览,这些牛有两个属性,funness和smartness,现在要你求出怎么选,可以使所有牛的smartness和funness的最大,并且这两个和都不能为负值
这一题很有意思,首先是这个问题是二维的,它包含两个属性,但是他有一个很重要的条件就是牛只能选一次,所以我们一开始就很容易想到用背包貌似可以求解,但是这一题没有办法直接用背包,因为没有直接给出价值和容量(他给了两个价值)。
但是,我们稍微变换一下,这一题就可以做了,我们要把一个看成是价值,把另一个看成是容量(容量随着包(牛)的增加而增加,可以视为无限)。但是很不幸的是,这一题是有负值的,但是没有关系,因为这一题的两个价值都是有范围的,所以我们可以采用把背包的中点定在半个范围内就可以了(相当于+range/2),那么最终我们把一个在二维展开的问题(求横纵坐标的和的最大值)转化为了一维背包的问题,求解的过程是和01背包是一样的,在负值的时候稍微注意一下反转求解方向就可以了(但是这一题可以剪枝,等一下讲)。
到目前为止我们先入为主讲明白了这一题可以用01背白做,但是为什么呢?其实我自己一开始做的时候是按照离散的思想把100个包按照f+s的大小从小到大排,然后想按照像3666那样做DP,但是这样是不行的,因为我们无法确定负值的时候是否放入包,这样就会很麻烦(其实我自己也不知道自己是怎么想的),那么在这一题,我为什么可以把f看成价值把s看成容量?其实我们把另一个看成价值也是没问题的,其实价值和容量是可以互换的,容量其实是无限的,我们只是把他的解的区间固定在一个位置上,然后相当于是定住一个量,来求另一个量的最大值,因为我们我们用的是背包,所以我们价值的那个量一定是完全求解的,题目要我们求最大值,所以我们只用求出价值的最大值,那么最优解一定在最后的全局解内出现。
最后说一下裁枝的问题,我们可以看到,如果我们只用简单的背包去求,那么会浪费大量的时间在无用的背包赋值(比如在i=1的时候,1000以后的背包值根本不可能有意义),所以我们根据到第几个背包来逐步扩大范围,减少求解的范围,节约时间。
#include <iostream>
#include <functional>
#include <algorithm> using namespace std;
typedef struct _cows
{
int smart;
int fun;
}Cows_Set; static Cows_Set cows[];
static int dp[ * * + ]; void Search(const int); int main(void)
{
int n;
while (~scanf("%d", &n))
{
for (int i = ; i < n; i++)
scanf("%d%d", &cows[i].smart, &cows[i].fun);
Search(n);
}
return ;
} void Search(const int n)
{
//01背包处理二维情况,要把一个看成容量,另一个看成价值 int root = n * , max_range = root * + , ans = 0xf0f0f0f0, tmp_max, tmp_min;
fill(dp, dp + max_range, 0xf0f0f0f0); dp[root] = ;//01背包,就是把这个位置定为0,其他地方都是"不合法" for (int i = ; i < n; i++)
{
tmp_max = root + i * + cows[i].smart;//对区间剪枝
tmp_min = root - i * + cows[i].smart;
if (cows[i].smart >= )
{
for (int j = tmp_max; j >= tmp_min; j--)
dp[j] = max(dp[j], dp[j - cows[i].smart] + cows[i].fun);
}
else
{
for (int j = tmp_min; j <= tmp_max; j++)
dp[j] = max(dp[j], dp[j - cows[i].smart] + cows[i].fun);
}
} for (int i = root; i < max_range; i++)
if (dp[i] >= )
ans = max(ans, i - root + dp[i]); printf("%d\n", ans);
}
DP:Cow Exhibition(POJ 2184)(二维问题转01背包)的更多相关文章
- Cow Exhibition POJ - 2184
题目地址:https://vjudge.net/problem/POJ-2184 下面的解释是从一个大佬那搬来的,讲的很清楚题意:给定一些奶牛,每个牛有s和f两个属性值,有正有负,要求选出一些牛,使得 ...
- HDU 3496 (二维费用的01背包) Watch The Movie
多多想看N个动画片,她对这些动画片有不同喜欢程度,而且播放时长也不同 她的舅舅只能给她买其中M个(不多不少恰好M个),问在限定时间内观看动画片,她能得到的最大价值是多少 如果她不能在限定时间内看完买回 ...
- POJ 1724 二维费用最短路
题目大意:有N个城市,编号1-N有R条路,每条路(单向)的起点为Si,终点为Di,长度为Li,如果要走这条路需要花Ti的钱现在你只有K元钱,求在不超支的前提下,从1走到N需要的最短距离 这里总是希望路 ...
- POJ 2155 二维线段树 经典的记录所有修改再统一遍历 单点查询
本来是想找一个二维线段树涉及懒惰标记的,一看这个题,区间修改,单点查询,以为是懒惰标记,敲到一半发现这二维线段树就不适合懒惰标记,你更新了某段的某列,但其实其他段的相应列也要打标记,但因为区间不一样, ...
- POJ Washing Clothes 洗衣服 (01背包,微变型)
题意:有多种颜色的衣服,由两个人合作来洗,必须洗完一种颜色才能洗下一种,求需要多少时间能洗完. 思路:将衣服按颜色分类,对每种颜色进行01背包,容量上限是该种颜色衣服全部洗完的耗时长一半,其实就是在最 ...
- POJ Charm Bracelet 挑饰品 (常规01背包)
问题:去珠宝店抢饰品,给出饰品种数n,能带走的重量m,以及每种饰品的重量w与价值v.求能带走的最大量. 思路:常规01背包. #include <iostream> using names ...
- POJ 1195 二维树状数组
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18489 Accepted: 8558 De ...
- poj 1948二维01背包
题意:给出不多于40个小棍的长度,求出用所有小棍组成的三角形的最大面积. 思路:三角形3边求面积,海伦公式:p=(a+b+c)/2;S=p*(p-a)*(p-b)*(p-c);因为最大周长为1600 ...
- Cornfields POJ - 2019(二维RMQ板题)
就是求子矩阵中最大值与最小值的差... 板子都套不对的人.... #include <iostream> #include <cstdio> #include <sstr ...
随机推荐
- Linux内核循环链表经典分析和移植
为什么说这个链表做的经典呢,哥哥我从Linux内核里边儿扣出来的,要么怎么说内核不是一般人能写的,这代码太TM优美了! 这里有一篇参考文章:http://isis.poly.edu/kulesh/st ...
- ExtJS请求验证方法
//登录连接数据库验证 function loginCheck() { var UserName = Ext.getCmp("UserName").getValue(); var ...
- 设置二级域名共享一级域名Cookie和删除共享Cookie
设置共享Cookie: 二级域名要想共享一级域名的cookie,只需要设置cookie.Domain = ".一级域名.com"; 删除共享Cookie: HttpCook ...
- 同一个解决方案"引用"其他的项目出现感叹号...
项目A是自己新建的... 但是项目B是"添加"→"现有项目"添加的... 所以项目B引用项目A的时候,引用的项目A显示感叹号... 项目A右击"属性& ...
- activti表结构
1.结构设计 1.1. 逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...
- 【C语言入门教程】5.1 函数说明 与 返回值
C 语言是结构化语言,它的主要结构成分是函数.函数被作为一种构件,用以完成程序中的某个具体功能.函数允许一个程序的各个任务被分别定义和编码,使程序模块化.本章介绍 C 语言函数的设计,如何用函数分解程 ...
- 解决mvc部署在IIS上以后出现404错误
首先:aspnet_regiis -i 如果还不行,更改web.config文件,添加红色的部分 <system.webServer> <modules runAllManagedM ...
- 第一款支持容器和云部署的开源数据库Neo4j 3.0
导读 Neo4j 3.0.0 正式发布,这是 Neo4j 3.0 系列的第一个版本.此版本对内部架构进行了全新的设计:提供给开发者更强大的生产力:提供更广阔的部署选择.Neo4j 3.0 被认为是世界 ...
- leetcode 74. Search a 2D Matrix
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...
- [codevs1022]覆盖
[codevs1022]覆盖 试题描述 有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地.如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积. ...