本文转载,出处: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. log4j自动生成日志文件配置

    生成文件到默认位置: #生成日志文件 #log4j.appender.systemFile=org.apache.log4j.RollingFileAppender #按天生成 log4j.appen ...

  2. linux kernel with param

    Linux kernel support pass param to kernel, this params can be assigned at load time by insmod or mod ...

  3. Fedora 19 配置参考

    1. 安装完Fedora 19之后,第一件事不是升级系统,而是添加源. 下载我配置好的源,非常全面,适用Fedora 19 x86_64.点我下载 打开终端,切换到repo.zip所在目录:mv re ...

  4. SNRO:Number Range

    业务对象是在一定的编号范围内分配编号的,编号既可以是内部分配也可以是外部分配.对于外部分配,用户输入编号,系统检查这个编号是否被占用.对于内部分配,系统会自动的把编号分配给业务对象.所以内部分配和外部 ...

  5. ARM公布“物联网”嵌入式mbed OS系统软件平台

    继ARM公司发布了为嵌入式微控制器设计的Cortex-M7架构处理器,ARM又公布了专为廉价低功耗“物联网”设计的新版软件及系统平台,以加速物联网设备的发展及部署.该软件为基于ARM现有Cortex- ...

  6. win7 php5.5 apache 源码安装 imagick扩展

    最近公司项目有用到php 的imagick,折腾了好长时间才把扩展装上,最主要的就是最新的不一定是最合适的,最开始一直找最新包安装,一直都不成功,经过google了好长时间,终于找到一个有用的,灵机一 ...

  7. 正则匹配 去掉 多余的js和html标签

    $reg17 = '/><strong>公司介绍<\/strong><\/td>([\S\s*]+?)<\/div>/'; $this->d ...

  8. c#配置log4net步骤

    1.引入添加log4net.dll引用 2.建立配置文件Log4Net.config(名字自定义).文件内容参考,输出的文件名称可更改 .运行是要放入到相应bin/debug(release) 目录 ...

  9. unpipc.h&unpipc.c

    unpipc.h #ifndef _UNPIPC_H #define _UNPIPC_H #include <stdio.h> #include <unistd.h> #inc ...

  10. Python标准库 urllib2 的使用

    1.Proxy 的设置 urllib2 默认会使用环境变量 http_proxy 来设置 HTTP Proxy. 如果想在程序中明确控制 Proxy,而不受环境变量的影响,可以使用下面的方式 impo ...