POJ 2184 Cow Exhibition (01背包的变形)
本文转载,出处: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背包的变形)的更多相关文章
- [POJ 2184]--Cow Exhibition(0-1背包变形)
题目链接:http://poj.org/problem?id=2184 Cow Exhibition Time Limit: 1000MS Memory Limit: 65536K Total S ...
- POJ 2184 Cow Exhibition (01背包变形)(或者搜索)
Cow Exhibition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10342 Accepted: 4048 D ...
- POJ 2184 Cow Exhibition 01背包
题意就是给出n对数 每对xi, yi 的值范围是-1000到1000 然后让你从中取若干对 使得sum(x[k]+y[k]) 最大并且非负 且 sum(x[k]) >= 0 sum(y[k] ...
- poj 2184 Cow Exhibition(背包变形)
这道题目和抢银行那个题目有点儿像,同样涉及到包和物品的转换. 我们将奶牛的两种属性中的一种当作价值,另一种当作花费.把总的价值当作包.然后对于每一头奶牛进行一次01背包的筛选操作就行了. 需要特别注意 ...
- PKU 2184 Cow Exhibition 01背包
题意: 有一些牛,每头牛有一个Si值,一个Fi值,选出一些牛,使得max( sum(Si+Fi) ) 并且 sum(Si)>=0, sum(Fi)>=0 思路: 随便选一维做容量(比如Fi ...
- POJ 2184 Cow Exhibition(背包)
希望Total Smart和Totol Funess都尽量大,两者之间的关系是鱼和熊掌.这种矛盾和背包的容量和价值相似. dp[第i只牛][j = 当前TotS] = 最大的TotF. dp[i][j ...
- POJ 2184 Cow Exhibition【01背包+负数(经典)】
POJ-2184 [题意]: 有n头牛,每头牛有自己的聪明值和幽默值,选出几头牛使得选出牛的聪明值总和大于0.幽默值总和大于0,求聪明值和幽默值总和相加最大为多少. [分析]:变种的01背包,可以把幽 ...
- poj 2184 Cow Exhibition(dp之01背包变形)
Description "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - ...
- poj 2184 Cow Exhibition(01背包)
Cow Exhibition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10882 Accepted: 4309 D ...
随机推荐
- python 实现梯度下降
在多元线性回归中会用到梯度下降来计算参数值.这里我用python实现一个梯度下降版本. 这里多元线性方程为 y = A0+A1*x1+...+An* xn 数据输入格式,y表示 y \t x1 \t ...
- BMP文件格式分析
前两天要做一个读取bmp文件的小程序,顺便查找了一些关于BMP格式的文章,现在post上来. 简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运 ...
- App性能提升方法
总体思路:精简请求数 1.css sprit 图像拼合,将所有可拼接的所有图像拼接为一整张图像,然后再利用css中的position定位来处理,降低图片的请求数 2.懒加载:只渲染客户端用户可见区域[ ...
- 设置textview背景色为透明
UITextView *textView=[[UITextView alloc]initWithFrame:CGRectMake(20, 40, 150, 170)];//初始化并设置大小 textV ...
- php中each()与list()函数
<?php $fruit = array('a' => 'apple', 'b' => 'banana', 'c' => 'cranberry');reset($fruit); ...
- (转)android底部弹出iOS7风格对话选项框(QQ对话框)--第三方开源--IOS_Dialog_Library
本文转载于:http://blog.csdn.net/zhangphil/article/details/44940339 完成这个效果的是使用了 IOS_Dialog_Library 下载地址:ht ...
- CLR via C# I/O基元线程同步构造
1. 分为用户模式构造和内核模式构造 2. 用户模式构造 a.易失构造 在一个简单数据类型的变量上执行原子性读或写操作 VolaileWrite 强制address中的值在调用时写入,除此之外,按照源 ...
- jqueryGrid 内置的onclickSubmit afterSubmit
$(document).ready(function() { $('#jpgCustomers').jqGrid({ //url from wich data should be requested ...
- Python脚本控制的WebDriver 常用操作 <十五> 处理Navigation Bar
下面将使用WebDriver来模拟操作:选择一个Navigation bar的选项 测试用例场景 Navigation Bar可以看作是简单的类似于tab的导航栏.一般来说导航栏都是ul+li.先定位 ...
- JMS消息头
一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...