poj_2184_dp
2013-05-02 10:26
141 查看
题目描述:
给出一个序列cow的属性值。对应cow的属性有smartness 和
funess。要求:在smartess和funess加和都大于0的条件下,sum of
这两个值最大的一个cow序列求出的sum值。
解题思路:
对应于cow就是选或者不选两种可能,所以是0/1背包问题。对于这个问题,有两列值,不同于标准里的只有一个容量限制。等于我要求的是,按照smart为下标的数组,挨个加入一只cow,更新对应这个smart值的funess值最大可能是多少,最后做完背包更新,求大于0的那个smart数组的加和就可以了。
那么在那个过程中,就要判断更新是正向还是反向进行(我们知道0/1里都是反向进行的,本质是怕更新重复。这里有负值,所以需要注意更新方向。)
代码:
#include<stdio.h>
#include <stdlib.h>
#define MIN -10000001
#define N 100001
int s[1001], f[1001];
int f1
, f2
, n;
main(){
int i, v, min_st, max_st, tmp,
max, j;
scanf("%d",&n);
min_st = 0;
max_st = 0;
for(i=1;i<=n;i++){
scanf("%d %d",&s[i], &f[i]);
if(s[i]<0)
min_st += s[i];
else
max_st += s[i];
}
//printf("min_st:%d,
max_st:%d\n",min_st, max_st);
tmp = (0-min_st)
> max_st? (0-min_st) : max_st;
for(i=0;i<=tmp;i++){
f2[i] = MIN;
f1[i] = MIN;
}
for(i=1;i<=n;i++){
if(s[i]>=0){ //反向更新
for(v=max_st; v>=min_st+s[i]; v--){
if(v>=0 &&
v-s[i]>=0 &&
f2[v-s[i]]!=MIN)
f2[v] = f2[v-s[i]] + f[i] > f2[v] ? f2[v-s[i]] +
f[i] : f2[v] ;
if(v>=0 &&
v-s[i]<0 &&
f1[s[i]-v]!=MIN)
f2[v] = f1[s[i]-v] + f[i] > f2[v] ? f1[s[i]-v] +
f[i] : f2[v] ;
if(v<0 &&
f1[s[i]-v]!=MIN)
f1[0-v] = f1[s[i]-v] + f[i] > f1[0-v] ? f1[s[i]-v] +
f[i] : f1[0-v] ;
}
if(f2[s[i]]<f[i])
f2[s[i]] = f[i];
}else{ //正向更新
for(v=min_st; v<=max_st+s[i]; v++){
if(v<0 &&
v-s[i]>=0 &&
f2[v-s[i]]!=MIN)
f1[0-v] = f2[v-s[i]] + f[i] > f1[0-v] ? f2[v-s[i]] +
f[i] : f1[0-v] ;
if(v<0 &&
v-s[i]<0 &&
f1[s[i]-v]!=MIN)
f1[0-v] = f1[s[i]-v] + f[i] > f1[0-v] ? f1[s[i]-v] +
f[i] : f1[0-v] ;
if(v>=0 &&
f2[v-s[i]]!=MIN)
f2[v] = f2[v-s[i]] + f[i] > f2[v] ? f2[v-s[i]] +
f[i] : f2[v] ;
}
if(f1[0-s[i]]<f[i])
f1[0-s[i]] = f[i];
}
给出一个序列cow的属性值。对应cow的属性有smartness 和
funess。要求:在smartess和funess加和都大于0的条件下,sum of
这两个值最大的一个cow序列求出的sum值。
解题思路:
对应于cow就是选或者不选两种可能,所以是0/1背包问题。对于这个问题,有两列值,不同于标准里的只有一个容量限制。等于我要求的是,按照smart为下标的数组,挨个加入一只cow,更新对应这个smart值的funess值最大可能是多少,最后做完背包更新,求大于0的那个smart数组的加和就可以了。
那么在那个过程中,就要判断更新是正向还是反向进行(我们知道0/1里都是反向进行的,本质是怕更新重复。这里有负值,所以需要注意更新方向。)
代码:
#include<stdio.h>
#include <stdlib.h>
#define MIN -10000001
#define N 100001
int s[1001], f[1001];
int f1
, f2
, n;
main(){
int i, v, min_st, max_st, tmp,
max, j;
scanf("%d",&n);
min_st = 0;
max_st = 0;
for(i=1;i<=n;i++){
scanf("%d %d",&s[i], &f[i]);
if(s[i]<0)
min_st += s[i];
else
max_st += s[i];
}
//printf("min_st:%d,
max_st:%d\n",min_st, max_st);
tmp = (0-min_st)
> max_st? (0-min_st) : max_st;
for(i=0;i<=tmp;i++){
f2[i] = MIN;
f1[i] = MIN;
}
for(i=1;i<=n;i++){
if(s[i]>=0){ //反向更新
for(v=max_st; v>=min_st+s[i]; v--){
if(v>=0 &&
v-s[i]>=0 &&
f2[v-s[i]]!=MIN)
f2[v] = f2[v-s[i]] + f[i] > f2[v] ? f2[v-s[i]] +
f[i] : f2[v] ;
if(v>=0 &&
v-s[i]<0 &&
f1[s[i]-v]!=MIN)
f2[v] = f1[s[i]-v] + f[i] > f2[v] ? f1[s[i]-v] +
f[i] : f2[v] ;
if(v<0 &&
f1[s[i]-v]!=MIN)
f1[0-v] = f1[s[i]-v] + f[i] > f1[0-v] ? f1[s[i]-v] +
f[i] : f1[0-v] ;
}
if(f2[s[i]]<f[i])
f2[s[i]] = f[i];
}else{ //正向更新
for(v=min_st; v<=max_st+s[i]; v++){
if(v<0 &&
v-s[i]>=0 &&
f2[v-s[i]]!=MIN)
f1[0-v] = f2[v-s[i]] + f[i] > f1[0-v] ? f2[v-s[i]] +
f[i] : f1[0-v] ;
if(v<0 &&
v-s[i]<0 &&
f1[s[i]-v]!=MIN)
f1[0-v] = f1[s[i]-v] + f[i] > f1[0-v] ? f1[s[i]-v] +
f[i] : f1[0-v] ;
if(v>=0 &&
f2[v-s[i]]!=MIN)
f2[v] = f2[v-s[i]] + f[i] > f2[v] ? f2[v-s[i]] +
f[i] : f2[v] ;
}
if(f1[0-s[i]]<f[i])
f1[0-s[i]] = f[i];
}
相关文章推荐
- Cow Exhibition POJ - 2184 特殊的01背包,有助于理解dp循环方向
- poj 2184 dp(兼具聪明和幽默的奶牛)
- POJ 2184 DP
- DP:Cow Exhibition(POJ 2184)(二维问题转01背包)
- POJ 2184 DP
- Poj 2184 (dp)
- poj 2184(dp变形,进一步加深01背包)
- poj 2184 Cow Exhibition(dp之01背包变形)
- POJ 2184 Cow Exhibition(DP:01背包)
- poj 2184(dp变形,进一步加深01背包)
- [POJ 2184]Cow Exhibition[DP][01背包]
- poj 2184 Cow Exhibition dp
- poj 2184 DP
- POJ 2184 Cow Exhibition [dp 背包]
- POJ 2184 Cow Exhibition (dp)
- POJ 2184 Cow Exhibition(DP)
- poj 2576 dp背包/随机交换(体重均分)
- poj 1038 Bugs Integrated, Inc. __dp状态压缩
- poj 1651 区间dp
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】