传送门

Description

奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行了面试,确定了每头奶牛的智商和情商。

贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。

满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。

Input

  • 第一行:单个整数N,
  • 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,表示第i 头奶牛的智商和情商。

Output

  单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出0

Sample Input

-
-
- - -

Sample Output


Hint

选择第一头,第三头,第四头奶牛,智商和为−5+6+2 = 3,情商和为7−3+1 = 5。再加

入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的

1 ≤ N ≤ 400;−1000 ≤ Si; Fi ≤ 1000

Solution

  一眼看出这是个背包,然后…………然后呢???

  最初想法是些bool型背包,发现爆空间(8000000*8000000)直接GG,于是放弃,想到之前的栈做法写了一个栈,使用map判重,详见代码一。然后发现map的复杂度过高,并且占据的空间依然很大,于是GG。

  考虑状态压缩。

  由于数组的下标可以存储一定的信息,我们使用f[i]的值存储s=i时最大的f值,由于要求结果最大,s一定时f显然越大越好。于是满足无后效性。注意要对下标进行平移,使用maxup和maxdown记录当前更新的上限和下限,每次进行转移。

  剪枝:如果s和f都小于零,那么你们今日知罪又有何用?显然他们对答案不会有任何好的贡献,直接continue即可。

Code

#include<map>
#include<cstdio>
#include<algorithm>
#define maxn 10010
#define maxm 4000010 inline void qr(int &x) {
char ch=getchar();int f=;
while(ch>''||ch<'') {
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x*=f;
return;
} inline int max(const int &a,const int &b) {if(a>b) return a;else return b;}
inline int min(const int &a,const int &b) {if(a<b) return a;else return b;}
inline int abs(const int &x) {if(x>) return x;else return -x;} inline void swap(int &a,int &b) {
int c=a;a=b;b=c;return;
} struct Frog {
int s,f;
Frog() {s=f=;}
Frog(int x,int y) {s=x;f=y;}
};
Frog frog[maxm];
int top=;
inline bool operator <(const Frog &a,const Frog &b) {
if(a.s^b.s) return a.s<b.s;
return a.f<b.f;
} bool ins[maxn][maxn];
Frog temp; int n,a,b; inline bool cmp(const Frog &a,const Frog &b) {
int sa=a.s+a.f,sb=b.s+b.f;
return sa<sb;
} int main() {
qr(n);
for(int i=;i<=n;++i) {
a=b=;qr(a);qr(b);
if(a<=&&b<=) continue;
int t=top;
for(int j=;j<=t;++j) {
int da=frog[j].s+a,db=frog[j].f+b;
temp=Frog(da,db);
if(ins[da+][db+]) continue;
ins[da+][db+]=true;
frog[++top]=temp;
}
}
std::sort(frog+,frog++top,cmp);
for(int i=top;i;--i) {
if(frog[i].s>=&&frog[i].f>=) {
printf("%d\n",frog[i].s+frog[i].f);return ;
}
}
putchar('');putchar('\n');
return ;
}

代码1 map 45分

#include<cstdio>
#include<cstring>
#define maxn 800005 inline void qr(int &x) {
char ch=getchar();int f=;
while(ch>''||ch<'') {
if(ch=='-') f=-;
ch=getchar();
}
while(ch>=''&&ch<='') x=(x<<)+(x<<)+(ch^),ch=getchar();
x*=f;
return;
} inline int max(const int &a,const int &b) {if(a>b) return a;else return b;}
inline int min(const int &a,const int &b) {if(a<b) return a;else return b;}
inline int abs(const int &x) {if(x>) return x;else return -x;} inline void swap(int &a,int &b) {
int c=a;a=b;b=c;return;
} int n,frog[maxn],a,b,ans,maxup=,maxdown=;
const int away=; int main() {
qr(n);
std::memset(frog,-0x3f,sizeof frog);frog[away]=;
for(int i=;i<=n;++i) {
a=b=;qr(a);qr(b);
if(a<=&&b<=) continue;
int dd=maxdown+a;
if(a>) {
for(int j=maxup+a;j>=dd;--j)
frog[j]=max(frog[j],frog[j-a]+b);
maxup+=a;
}
else {
for(int j=dd;j<=maxup;++j)
frog[j]=max(frog[j],frog[j-a]+b);
maxdown+=a;
}
}
for(int i=away;i<=maxup;++i)
{
if(frog[i]>=) ans=max(frog[i]+i-away,ans);
}
printf("%d\n",ans);
return ;
}

Summary

  1、使用map且结构体为第一关键字时,需要重载合法的小于号供map使用,如果需要规则不同的sort,需要手写比较函数,不能重载运算符。

   2、二维dp且空间较大的时候可以考虑状压,把其中一维作为下标处理。

   3、这题是怎么被评到绿题去的??我怎么做着和黑题一样

【DP】【P2340】奶牛会展的更多相关文章

  1. P2340 奶牛会展(状压dp)

    P2340 奶牛会展 题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由 ...

  2. P2340 奶牛会展 DP 背包

    P2340 奶牛会展 DP \(n\)头牛,每头牛有智商\(s[i]\)情商\(f[i]\),问如何从中选择几头牛使得智商情商之和最大 且 情商之和.智商之和非负 \(n\le 400,-10^3\l ...

  3. 洛谷P2340 奶牛会展

    题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由于负的智商或情商会造成 ...

  4. 【题解】 洛谷P2340 奶牛会展

    传送门 重新开始打代码Day1 第一眼看感觉不对啊,这道题目好像空间开不下,是不是不能dp... 后来想到了一个思路,他要求的是\(dp_{i,j,k}=j+k\),然后这样子不是很奇怪吗? 直接一维 ...

  5. 【Luogu】P2340奶牛会展

    题目链接 突发奇想可以用f[i]表示智商和为i的时候情商最大是多少.这样就变成了一个背包问题. 最后更新答案的时候从0到最大背包容量遍历,最后答案是最大的i+f[i]; 但是虽然答案只能从0到m里选, ...

  6. 【洛谷P2340】 奶牛会展

    \(奶牛会展\) 题目链接 由于智商之和或情商之和不能为负数,所以直接把智商+情商>0的奶牛加上是布星的 我们考虑背包,不妨将智商当做物品大小,将情商当做价值 我们要求 大小+价值 的最大值 \ ...

  7. [USACO]奶牛会展(背包)

    [USACO]奶牛会展 题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览. ...

  8. 【dp】奶牛家谱 Cow Pedigrees

    令人窒息的奶牛题 题目描述 农民约翰准备购买一群新奶牛. 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛.这些奶牛间的关系可以用二叉树来表示.这些二叉树总共有N个节点(3 <= N < ...

  9. 线性dp 之 奶牛渡河

    题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...

随机推荐

  1. kettle_简单入门

    简介 Kettle是一款纯Java开发的ETL工具,它是跨平台的,所以它可以在Window.Linux.Unix上运行.注意什么是ETL,读者可以自行百度了解,我的理解是将一个数据库的数据导入到另外一 ...

  2. 2>&1和&>的区别

    简单记录下: COMMAND > /path/file 2>&1 COMMAND &> /path/file 这两个效果都是一样的,都是把正确的输入.错误输入存放到同 ...

  3. lintcode39 恢复旋转排序数组

    恢复旋转排序数组   给定一个旋转排序数组,在原地恢复其排序. 您在真实的面试中是否遇到过这个题? Yes 说明 什么是旋转数组? 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3 ...

  4. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)

    @author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...

  5. js中的数组对象排序

    一.普通数组排序 js中用方法sort()为数组排序.sort()方法有一个可选参数,是用来确定元素顺序的函数.如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序.如: var ar ...

  6. C++标准库算法

    一.只读算法 1. find() 2. count() 3. accumulate 4. equal 二.写入算法 1. fill 2. fill_n 3. copy 4. replace 5. re ...

  7. Java学习个人备忘录之文档注释

    文档注释 单行注释用 // 多行注释有两种,第一种是 /* 内容 */,第二种是/** 内容 */. 这两种多行注释的区别是/** 内容 */这种注释可以生成一个该文件的注释文档,下面是演示代码. A ...

  8. 对Objective-C中runtime的理解

    Objective-C是面向runtime(运行时)的语言,在应用程序运行的时候来决定函数内部实现什么以及做出其它决定的语言.程序员可以在程序运行时创建,检 查,修改类,对象和它们的方法,Object ...

  9. TCP系列24—重传—14、F-RTO虚假重传探测

    一.虚假重传 在一些情况下,TCP可能会在没有数据丢失的情况下初始化一个重传,这种重传就叫做虚假重传(Spurious retransmission).发生虚假重传的原因可能是包传输中重排序.传输中发 ...

  10. 3dContactPointAnnotationTool开发日志(二三)

      smpl模型得是一个整体,于是我让子物体的选项卡的删除按钮消失,这样就不会删除不必要的东西然后产生奇怪现象: