本文转载,出处: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. python 实现梯度下降

    在多元线性回归中会用到梯度下降来计算参数值.这里我用python实现一个梯度下降版本. 这里多元线性方程为 y = A0+A1*x1+...+An* xn 数据输入格式,y表示 y \t x1 \t ...

  2. BMP文件格式分析

    前两天要做一个读取bmp文件的小程序,顺便查找了一些关于BMP格式的文章,现在post上来. 简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运 ...

  3. App性能提升方法

    总体思路:精简请求数 1.css sprit 图像拼合,将所有可拼接的所有图像拼接为一整张图像,然后再利用css中的position定位来处理,降低图片的请求数 2.懒加载:只渲染客户端用户可见区域[ ...

  4. 设置textview背景色为透明

    UITextView *textView=[[UITextView alloc]initWithFrame:CGRectMake(20, 40, 150, 170)];//初始化并设置大小 textV ...

  5. php中each()与list()函数

    <?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');reset($fruit); ...

  6. (转)android底部弹出iOS7风格对话选项框(QQ对话框)--第三方开源--IOS_Dialog_Library

    本文转载于:http://blog.csdn.net/zhangphil/article/details/44940339 完成这个效果的是使用了 IOS_Dialog_Library 下载地址:ht ...

  7. CLR via C# I/O基元线程同步构造

    1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...

  8. jqueryGrid 内置的onclickSubmit afterSubmit

    $(document).ready(function() { $('#jpgCustomers').jqGrid({ //url from wich data should be requested ...

  9. Python脚本控制的WebDriver 常用操作 <十五> 处理Navigation Bar

    下面将使用WebDriver来模拟操作:选择一个Navigation bar的选项 测试用例场景 Navigation Bar可以看作是简单的类似于tab的导航栏.一般来说导航栏都是ul+li.先定位 ...

  10. JMS消息头

    一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...