"Fat and docile, big and dumb, they look so stupid, they aren't much 
fun..." 
- Cows with Guns by Dana Lyons

The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be put on by the cows. She has given each of the N (1 <= N <= 100) cows a thorough interview and determined two values for each cow: the smartness Si (-1000 <= Si <= 1000) of the cow and the funness Fi (-1000 <= Fi <= 1000) of the cow.

Bessie must choose which cows she wants to bring to her exhibition. She believes that the total smartness TS of the group is the sum of the Si's and, likewise, the total funness TF of the group is the sum of the Fi's. Bessie wants to maximize the sum of TS and TF, but she also wants both of these values to be non-negative (since she must also show that the cows are well-rounded; a negative TS or TF would ruin this). Help Bessie maximize the sum of TS and TF without letting either of these values become negative.

Input

* Line 1: A single integer N, the number of cows

* Lines 2..N+1: Two space-separated integers Si and Fi, respectively the smartness and funness for each cow.

Output

* Line 1: One integer: the optimal sum of TS and TF such that both TS and TF are non-negative. If no subset of the cows has non-negative TS and non- negative TF, print 0.

Sample Input

5
-5 7
8 -6
6 -3
2 1
-8 -5

Sample Output

8

Hint

OUTPUT DETAILS:

Bessie chooses cows 1, 3, and 4, giving values of TS = -5+6+2 = 3 and TF 
= 7-3+1 = 5, so 3+5 = 8. Note that adding cow 2 would improve the value 
of TS+TF to 10, but the new value of TF would be negative, so it is not 
allowed. 

 
显然是个0/1背包 把 s 当做体积,f 当做重量就可以。
 但是问题在于物品的体积有负数。
一般情况下,我们做的背包都是体积在一个以 0 为左端点的区间。
这道题变成了 一个 -1000*100 到 1000*100 的区间,我们可以将这个区间整体向右平移 100000
这样的话 原点移动到了 100000 这个点。左端点从 -1000*100 变成了 0
然后再分类讨论 s 的正负,进而决定是从大到小还是从小到大dp
 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int inf = <<;
const int dir = ;
int dp[];
struct s{
int s, f;
}arr[]; int main(){
int n;
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d%d",&arr[i].s,&arr[i].f); for(int i=;i<=;i++)
dp[i] = -inf;
dp[] = ; for(int i=;i<n;i++){
if(arr[i].s < && arr[i].f < )
continue;
if(arr[i].s>){
for(int j=;j>=arr[i].s;j--){
if(dp[j-arr[i].s] > -inf){
dp[j] = max(dp[j],dp[j-arr[i].s]+arr[i].f);
}
} }else {// arr[i].s < 0 arr[i].f>=0
for(int j=arr[i].s;j<=+arr[i].s;j++){
if(dp[j-arr[i].s] > -inf){
dp[j] = max(dp[j],dp[j-arr[i].s]+arr[i].f);
}
}
}
}
int ans = ;
for(int i=;i<=;i++){
if(dp[i]>=)
ans = max(ans, dp[i]+i-);
}
printf("%d\n",ans);
return ;
}

对代码进行了优化。

首先是将dp从数组名变成了指针,令dp指向buf[100000]

这样、数组下标为负数时也不会越界。

优化关键在设置了两个变量,分别记录了有效区间的两个端点。

比如说 在处理第一个数的时候整个区间的都是无法达到的(除了原点)

而再像优化前的代码一样遍历一个200000的区间是无用的冗余。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int inf = <<;
int buf[];
int *const dp = buf + ; int main(){
int n, s, f;
scanf("%d",&n); for(int i=;i<=;i++)
buf[i] = -inf;
dp[] = ;// dp[0] == buf[100000] int l = , r = ;// 有效区间的左端点和右端点
for(int i=;i<n;i++){
scanf("%d%d",&s,&f);
if(s< && f <)//舍弃无用点
continue;
if(s > ){// 体积为正数 所以从大到小dp
for(int i=r;i>=l;i--)
dp[i+s] = max(dp[i+s],dp[i]+f);
}else {
for(int i=l;i<=r;i++)
dp[i+s] = max(dp[i+s],dp[i]+f);
}
if(s>)
r += s;
else
l += s;
}
int ans = ;
for(int i=;i<=r;i++){
if(dp[i] >= )
ans = max(ans, dp[i]+i);
}
printf("%d\n",ans);
return ;
}
 

POJ 2184 Cow Exhabition的更多相关文章

  1. POJ 2184 Cow Exhibition【01背包+负数(经典)】

    POJ-2184 [题意]: 有n头牛,每头牛有自己的聪明值和幽默值,选出几头牛使得选出牛的聪明值总和大于0.幽默值总和大于0,求聪明值和幽默值总和相加最大为多少. [分析]:变种的01背包,可以把幽 ...

  2. [POJ 2184]--Cow Exhibition(0-1背包变形)

    题目链接:http://poj.org/problem?id=2184 Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  3. poj 2184 Cow Exhibition(dp之01背包变形)

    Description "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - ...

  4. POJ 2184 Cow Exhibition (01背包变形)(或者搜索)

    Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10342   Accepted: 4048 D ...

  5. poj 2184 Cow Exhibition(01背包)

    Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10882   Accepted: 4309 D ...

  6. POJ 2184 Cow Exhibition (01背包的变形)

    本文转载,出处:http://www.cnblogs.com/Findxiaoxun/articles/3398075.html 很巧妙的01背包升级.看完题目以后很明显有背包的感觉,然后就往背包上靠 ...

  7. poj 2184 Cow Exhibition

    // 给定n头牛,每头有属性智商和幽默感,这两个属性值有正有负,现在要从这n头牛中选出若干头使得他们的智商和与幽默感和不为负数,// 并且两者两家和最大,如果无解输出0,n<=100,-1000 ...

  8. poj 2184 Cow Exhibition(背包变形)

    这道题目和抢银行那个题目有点儿像,同样涉及到包和物品的转换. 我们将奶牛的两种属性中的一种当作价值,另一种当作花费.把总的价值当作包.然后对于每一头奶牛进行一次01背包的筛选操作就行了. 需要特别注意 ...

  9. POJ 2184 Cow Exhibition 01背包

    题意就是给出n对数 每对xi, yi 的值范围是-1000到1000 然后让你从中取若干对 使得sum(x[k]+y[k]) 最大并且非负   且 sum(x[k]) >= 0 sum(y[k] ...

随机推荐

  1. easy-im:一款基于netty的即时通讯系统

    介绍 easy-im是面向开发者的一款轻量级.开箱即用的即时通讯系统,帮助开发者快速搭建消息推送等功能. 基于easy-im,你可以快速实现以下功能: + 聊天软件 + IoT消息推送 基本用法 项目 ...

  2. 由Oracle 11g SYSAUX 和 SYSTEM 表空间回收引发的联想

    0x00--目的 整理一下以前一个SYSTEM表空间和SYSAUX表空间使用率达到99%上限的处理思路和相关知识点,好记性不如烂笔头 0x01--表空间使用率现状 通过查询可得知目前表空间使用情况如下 ...

  3. 选择排序_c++

    选择排序_c++ GitHub 文解 选择排序的核心思想是对于 N 个元素进行排序时,对其进行 K = (N - 1) 次排序,每次排序从后(N + 1 - K)个数值中选择最小的元素与以 (K - ...

  4. 原生js实现简单的随机点名系统

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  5. About Me - 关于

    0x00 简介 97年生 计算机相关专业,无线电安全攻防方向. 涉猎较多,喜欢研究无线.硬件.软件.网络.攻击.检测.防御等各类安全技术 精通较少,主要擅长的还是硬件.渗透.无线攻击方面. 现阶段在研 ...

  6. Resharp常用设置收集整理

    F12跳转的问题:

  7. window.moveTo(),window.moveBy()不生效

    window.moveTo()和window.moveBy的菜鸟教程介绍: moveTo() 方法可把窗口的左上角移动到一个指定的坐标. window.moveTo(x,y) moveBy() 方法可 ...

  8. 关于js代码位置的第一次总结

    最近在学习dom树节点操作时,发现查找结点总是返回null,原因在于将js代码放在了head里,因为页面是从上往下逐行加载,在还未加载相关节点时当然查找不到,返回值为null. 而对于另一句老生常谈的 ...

  9. Kibana6.3.1安装

    Kibana安装 Kibana官方下载地址: https://www.elastic.co/cn/downloads/kibana 也可以直接使用以下命令下载(文章下载目录一概为/home/tools ...

  10. PHPExcel 导入Excel数据 (导出下一篇我们继续讲解)

    一:使用composer下载 phpoffice/phpexcel 或者直接下载安装包 composer require phpoffice/phpexcel 二 1:导入数据 原理:读取文件,获取文 ...