poj2184 Cow Exhibition(处理带负数的01背包)

博客介绍了如何解决一个变形的01背包问题,即在保证智商和幽默度非负的情况下,选择牛参赛以最大化两者之和。通过扩展数组范围,将负数转换为正数进行处理,并定义dp数组来确定不同背包容量下的最大幽默度和智商之和。由于负数的存在,需要从小到大遍历以避免错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**题意:**要求从N头牛中选择若干头牛去参加比赛,假设这若干头牛的智商之和为sumS,幽默度之和为sumF现要求在所有选择中,在使得sumS>=0&&sumF>=0的基础上,使得sumS+sumF最大并输出其值.

**思路:**算是01背包的变形。由于出租下标不能为负数,我们可以将数组范围扩大,不再以0来区分正负数,而是换一个数来区分,这里取了1e5来区分正负数。(因为正负数的最大范围是100*1000),然后这题也不像常规的01背包一样明确的指出什么是背包容量,什么是价值。所以,这里应该需要我们自己来制定。这里取了s为背包容量,f为物品价值。
所以定义dp[i]表示s为i的时候f的最大值。
最后求解答案的时候遍历[100000,200000]的区间即可。

还有一点,由于负数的存在,所以01背包需要讨论,参考了以为大佬的博客内容。

在一般的01背包压缩空间的时候,体积的遍历是从大到小,因为dp[v]=max(dp[v],dp[v-c[i]]+w[i]),当前的dp[v]只取决于比自己小的dp[v-c[i]],所以从大到小遍历时每次dp[v-c[i]]和dp[v]都是上一次的状态。
如果体积为负v-c[i]>v,从大到小遍历dp[v-c[i]]是当前物品的状态,不是上一个,这样就会出错,解决的办法是从小到大遍历。

#include <iostream>
#include <cstdio>
#include  <algorithm>
#include <assert.h>
#include <cstdlib>
#include  <cstring>
using namespace std;
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值