POJ 2184(01背包)(负体积)

http://poj.org/problem?id=2184

http://blog.csdn.net/liuqiyao_01/article/details/8753686

对于负体积问题,可以先定义一个“零点”shift,将dp[shift]设为0,其他都设为-INF。

然后负体积从0往maxn+cost更新,正体积从maxn往shift更新。

最后从shift到maxn中找最大值,shift以下的值不会被遍历到

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;

#define MEM(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define debug printf("!\n")
#define INF (0x3f3f3f3f)
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ep 1e-6

const int shift = 10000;
const int MAXN  = 210000;
const int MAXM = 105;

int dp[MAXN];

int ci[MAXM];//容量
int wi[MAXM];//价值
int n,V,i,j,v,t,sum;
double G;

void zeroOnePack(int cost,int weight)
{
          if(cost>=0)
          {
                    for(v = MAXN-1;v>=cost;v--)
                    {
                              dp[v] =MAX(dp[v],dp[v-cost]+weight);
                    }
          }
          else
          {
                    for(v = 0;v<MAXN+cost;v++)
                    {
                              dp[v] =MAX(dp[v],dp[v-cost]+weight);
                    }
          }
}

int main()
{
          while(sf("%d",&n)!=EOF)
          {

                    MEM(dp,-INF);
                    MEM(wi,0);

                    for(i = 0;i<n;i++)
                    {
                              sf("%d",&ci[i]);
                              sf("%d",&wi[i]);
                    }

                    dp[shift] = 0;

                    for(i = 0;i<n;i++)
                    {
                              zeroOnePack(ci[i],wi[i]);
                    }

                    int ans = -INF;

                    for(i = shift;i<MAXN;i++)
                    {
                              if(dp[i]>=0 && (i-shift+dp[i])>ans)
                                        ans = i-shift+dp[i];
                    }
                    pf("%d\n",ans);

          }
    return 0;
}
/*
5
-5 7
8 -6
6 -3
2 1
-8 -5
*/
时间: 2024-10-17 00:04:13

POJ 2184(01背包)(负体积)的相关文章

poj 2184 0---1背包的变形

这题是0--1背包的变形,对理解0--1背包有很大的帮组 题意:要选一些牛去参见展览,每个牛有幽默.智慧两个选择标准,要求选的这些牛使得幽默和智慧的总和最大且幽默和智慧的每个总和都必须是大于等于0: 刚看的这个题目是时候,知道是一个0--1背包的的题目,但就是不知道怎么来写出状态转移方程,因为题中的两个变量都是有负值的. 看了大牛的解题报告才知道. 我们可以把幽默个变量看成是体积 , 智慧看成是价值. 我们可以把每个牛幽默的值 , 放在一个坐标上,让后整体往右移,使得最小值为 0 , 那么这时候

POJ 2184 01背包+负数处理

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10200   Accepted: 3977 Description "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - Cows with Guns by Dana Lyons The cows want to prove to

Cow Exhibition POJ 2184(01背包dp)

原题 题目链接 题目分析 明显的01背包,但还是由细节需要处理,设置dp[i][j]=前i头牛中选的TF为j时最大的TS值,由于TF可能为负数因此要加一个基数使其在大于等于零,dp初始化为-1,dp[0][0]=0.更新的时候dp[i][j]=max(dp[i-1][j-f[i]]+s[i],dp[i-1][j]).观察这个dp的更新可以发现能状态压缩,当f[i]>=0时,j从大到小更新,当f[i]<0时,j从小到大更新.最后从基数往上扫dp[j]+j-基数的最大值就是答案,注意前提是dp[i

poj 1837 01背包

Balance Time Limit: 1000 MS Memory Limit: 30000 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Gigel has a strange "balance" and he wants to poise it. Actually, the device is different fr

POJ 3624 01背包

初学DP,用贪心的思想想解题,可是想了一个多小时还是想不出. //在max中的两个参数f[k], 和f[k-weight[i]]+value[i]都是表示在背包容量为k时的最大价值 //f[k]是这个意思,就不用说了. //而f[k-weight[i]]+value[i]也表示背包容量为k时的最大价值是为什么呢? //首先,f[k-weight[i]]表示的是背包容量为k-weight[i]的容量,也就是说f[k-weight[i]] //表示的是容量还差weiht[i]才到k的价值,+walu

hdu 2184 01背包变形

转自:http://blog.csdn.net/liuqiyao_01/article/details/8753686 题意:这是又是一道01背包的变体,题目要求选出一些牛,使smartness和funness值的和最大,而这些牛有些smartness或funness的值是负的,还要求最终的smartness之和以及funness之和不能为负. 这道题的关键有两点:一是将smartness看作花费.将funness看作价值,从而转化为01背包:二是对负值的处理,引入一个shift来表 示“0”,

POJ之01背包系列

poj3624 Charm Bracelet 模板题 没有要求填满,所以初始化为0就行 #include<cstdio> #include<iostream> using namespace std; #define N 15010 int n,m,v[N],c[N],f[N]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&am

Relocation POJ - 2923(01背包+状压dp)

Relocation POJ - 2923 原文地址:https://www.cnblogs.com/megadeth/p/11361007.html

poj 2184 Cow Exhibition (变形的01背包)

链接:poj 2184 题意:给定n头牛,每头牛的的智商(si)和幽默感(fi)已知,求在保证智商(S)的和及幽默感(F)的和都为非负的情况下,智商和幽默感(S+T)的最大值 分析:题的本质即从n头牛中选出S>=0&&T>=0时,S+T的最大值 以智商最为容量,幽默感作为价值,因为每头牛只能选一次,就转化01背包了, dp[i]为智商为i时幽默感的最大值,则状态转移方程为 dp[j]=max(dp[j],dp[j-s[i]]+f[i]); 但是智商总和范围-100000~100