| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 9424 | Accepted: 3619 |
Description
Input
Output
Sample Input
5 -5 7 8 -6 6 -3 2 1 -8 -5
Sample Output
8
Hint
题意:有一些牛,每个牛有智力S和幽默感F两个属性,(TS是智力的和, TF是幽默感的和)求从中选出一些牛,使他们的TS与TF不为非负数,且TS+TF最大。
分析:我们可以将某一属性作为体积,另一个就当做价值,这样就转换成了背包问题。 又因为其中有负数,所以我们将原点移动到1000*100+5位置,这样就不会RE了。
心得:原来不懂,所以就百度了下,,然后就觉得:真的是道好题,开阔了眼界。。。没想到还可以这样,orz。
代码:
#include <stdio.h>
#include <string.h>
#define Min -0x3f3f3f3f
#define M 100005
int dp[M<<1];
int Max(int a, int b){
return a>b?a:b;
}
int main(){
int n, i, j;
while(scanf("%d", &n) == 1){
int mid, min, max;
mid = min = max = M;
//memset(dp, 0, sizeof(dp));
for(i = 0; i < (M<<1); i ++) dp[i] = Min; //注意初始化都初始化最小值,因为有负值,这样取dp[j+s] = Max(dp[j+s], dp[s]+f)就不会加上一个f而大于0,影响答案
dp[M] = 0;
int s, f;
for(i = 0; i < n; i ++){
scanf("%d%d",&s, &f);
if(s > 0){
for(j = max; j >= min; j --)
dp[j+s] = Max(dp[j+s], dp[j]+f);
max += s;
}
else{
for(j = min; j <= max; j ++){
dp[j+s] = Max(dp[j+s], dp[j]+f);
}
min += s;
}
}
int flag = 0; int ans = 0;
/*printf("%d..\n", max);
printf("%d..\n", dp[max]);*/
for(i = mid; i <= max; i ++){
if(dp[i] >= 0){
ans = Max(ans, i-mid+dp[i]);
}
}
printf("%d\n", ans);
}
return 0;
}
poj 2184 Cow Exhibition 【另类01背包】
原文地址:http://blog.csdn.net/shengweisong/article/details/41495939