本文转载,出处:http://www.cnblogs.com/Findxiaoxun/articles/3398075.html

很巧妙的01背包升级。看完题目以后很明显有背包的感觉,然后就往背包上靠。把s看成是空间,f看成是价值,转换成了01背包经典模型(没有想到,,,)。可,s是负值,这就涉及到一个问题,如果按照普通的01背包,(01背包的倒序原因请参看这个http://hi.baidu.com/findxiaoxun/item/9abf560127a155c091571868)

for(int i=;i<n;i++)
for(int v=maxv;v>=vi[i];v--)
dp[v]=max{dp[v],dp[v-vi[i]]+w[i]}

循环物品的时候,看第一件,在此题中,我们先假设最大空间为5,则2->5的值都为3,

然后i=1,循环第二件,v=5->3,而dp[5]=max{dp[5],dp[5+1]+4},背包空间为6的位置,我们假设预置为0,则dp[5]=4;dp[4]=max{dp[4],dp[4-(-1)]+4};则dp[4]=4+4=8;其实到这个值,我们已经看出,如果按照正常的逆序,s为负值的物品不只使用一次,这与题目的要求是相悖的。那么,正序考虑。读者可以自行推导,证明其可行性。

而我们发现,背包空间出现了负值,下限是-100*1000;上限是100*1000;一个很容易想到的方法就是,把100*1000,作为我们的数轴上的0点。也就是背包空间变成2*100*1000,不过在考虑的时候,以100*1000为原点,左边实际上是负值,右边是正值。则dp[i]是数据中左边一列s的和为s时的最大f值,而s+f=dp[i]+i-10000;

初始预置为-INF,dp[orgpoint]=0的目的是为了从0原点开始,而且,只放可以放的点。用一两个样例思考下就能明白。

算法的可行性,其实最大的要求就是符合01背包的特点,每个物品后只有一件,只放一次。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int MAXN=;
const int INF=0x3f3f3f3f;
const int MAXV=*(int)1e5;
int dp[MAXV+];
int s[MAXN],f[MAXN];
int n;
int main(){
int orgpoint=(int)1e5;
while(scanf("%d",&n)!=EOF){
for(int i=;i<n;i++)scanf("%d%d",&s[i],&f[i]);
for(int i=;i<=MAXV;i++)dp[i]=-INF;
dp[orgpoint]=;
for(int i=;i<n;i++){
if(s[i]>){//>0 then in reversed order
for(int j=MAXV;j>=s[i];j--)//this order ensure that we put every item just for one time
if(dp[j-s[i]]>-INF)
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}else{//if negative number,have a look at the proof
for(int j=;j<MAXV+s[i];j++)
if(dp[j-s[i]]>-INF)
dp[j]=max(dp[j],dp[j-s[i]]+f[i]);
}
}
int ans=;
for(int i=;i<=;i++)
if(dp[i]>=&&dp[i]+i->ans)
ans=dp[i]+i-;
printf("%d\n",ans); }
return ;
}

代码参考http://www.cnblogs.com/kuangbin/archive/2012/09/14/2684929.html

最后附上本人的代码,其实差不多啦:

#include <iostream>
#include <stdio.h>
#include <string.h>
/*
AC
*/
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=;
const int V=;
int s[maxn],f[maxn];
int dp[V*+];
int n;
int main()
{
int a,b;
int sum=;
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%d%d",&a,&b);
s[i]=a;
f[i]=b;
}
//memset(dp,0,sizeof(dp)); //不能为0值。。。因为f[i]有小于0的值,应该取负无穷大的值
for(int i=;i<V*+;i++)
dp[i]=-INF;
dp[V]=;
for(int i=;i<n;i++){
if(s[i]>=){
for(int v=V*;v>=s[i];v--){ //倒叙
dp[v]=max(dp[v],dp[v-s[i]]+f[i]);
}
}
else{
for(int v=;v<=V*;v++){ //正序
dp[v]=max(dp[v],dp[v-s[i]]+f[i]);
}
}
}
for(int i=;i<=V*;i++){
if(i-+dp[i]>sum && dp[i]>=){
sum=i-+dp[i];
}
}
printf("%d\n",sum);
return ;
}

POJ 2184 Cow Exhibition (01背包的变形)的更多相关文章

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

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

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

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

  3. POJ 2184 Cow Exhibition 01背包

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

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

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

  5. PKU 2184 Cow Exhibition 01背包

    题意: 有一些牛,每头牛有一个Si值,一个Fi值,选出一些牛,使得max( sum(Si+Fi) ) 并且 sum(Si)>=0, sum(Fi)>=0 思路: 随便选一维做容量(比如Fi ...

  6. POJ 2184 Cow Exhibition(背包)

    希望Total Smart和Totol Funess都尽量大,两者之间的关系是鱼和熊掌.这种矛盾和背包的容量和价值相似. dp[第i只牛][j = 当前TotS] = 最大的TotF. dp[i][j ...

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

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

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

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

  9. poj 2184 Cow Exhibition(01背包)

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

随机推荐

  1. hibernate get VS load

    1.  执行get方法:会立即加载对象      而执行load方法,若不适用该对象,则不会立即执行查询操作,而返回一个代理对象      get立即检索,load延迟检索  2.  load方法可能 ...

  2. 【风马一族_Java】如何获取ACSLL表的值

    消耗两小时,只为一代码. 终于得到了此代码: public class sows { public static void main(String[] args) { byte[] bytes = n ...

  3. 13个SQL优化技巧

    避免无计划的全表扫描<!--?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  4. Centos(Linux) 根文件系统

    /下面的文件 /boot:系统启动相关的文件:如内核,inittrd ,以及MBR grub /dev :设备文件: 块设备:随机访问,数据块 如:USB 字符设备:线性访问,按字符为单位如:鼠标,按 ...

  5. 转:关于JAVA多线程同步

    转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖 ...

  6. Noesis.Javascript.dll 引用时报错“找不到指定的模块”

    Could not load file or assembly 'Noesis.Javascript.dll' or one of its dependencies. 找不到指定的模块. 通过反编译发 ...

  7. 用 Function.apply() 的参数数组化来提高 JavaScript程序性能

    我们再来聊聊Function.apply() 在提升程序性能方面的技巧. 我们先从 Math.max() 函数说起, Math.max后面可以接任意个参数,最后返回所有参数中的最大值. 比如 aler ...

  8. i18next-页面层语言国际化js框架介绍

    因为工作需要,最近研究了下网站语言国际化的问题,根据当前项目架构,寻求一种较好的解决方案.首先总结下项目中语言切换实现方式大概有以下几种: 1,一种语言一套页面,如:index_CN.html,ind ...

  9. [Android教程]TextView使用SpannableString设置复合文本

    TextView通常用来显示普通文本,但是有时候需要对其中某些文本进行样式.事件方面的设置.Android系统通过SpannableString类来对指定文本进行相关处理,具体有以下功能: 1.Bac ...

  10. Infobright高性能数据仓库

    1.  概述 Infobright是一款基于独特的专利知识网格技术的列式数据库.Infobright简单易用,快速安装部署,使用中无需复杂操作,能大幅度减少管理工作:在应对50TB甚至更多数据量进行多 ...