POJ2184 Cow Exhibition

来源:互联网 发布:什么是usb网络转换器 编辑:程序博客网 时间:2024/06/01 09:59

原题链接: http://poj.org/problem?id=2184
大意:有N个奶牛,每个奶牛都有两种属性,smart和fun,它们都有可能是负数。现在要从这n个奶牛中选一部分,使得选出的奶牛的smart和fun总和达到最大,同时smart的和以及fun的和都必须为正数。

思路:
这道题卡了好久好久,首先,它是0-1背包的一个变形,所以可以把smart看成容积,把fun看成价值。但是,这里容积有可能是负的,所以必须要进行转化。我觉得比较直观的方式是在输入之后,直接把每个smart都加1000,以确保每个smart都是正数。
下面提供两个代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>#include<time.h>#include<set>#include<stack>#include<vector>#include<map>#include<queue>#define pi acos(-1)#define maxn 111111#define maxm 11111#define INF 0x3F3F3F3F#define eps 1e-8#define pb push_back#define mem(a) memset(a,0,sizeof a)using namespace std;const long long mod = 1000000007;/**lyc**/void init() {}int dp[222222];int s[111];int f[111];int main() {    init();    int n;    while(scanf("%d", &n) != EOF) {        memset(dp, -INF, sizeof dp);        for(int i = 1; i <= n; i++) {            scanf("%d%d", s + i, f + i);        }        dp[100000] = 0;        for(int i = 1; i <= n; i++) {            if(s[i] < 0 && f[i] < 0) continue;            if(s[i] > 0) {                for(int j = 200000; j >= s[i]; j--) {                    if(dp[j - s[i]] > -INF) {                        dp[j] = max(dp[j], dp[j - s[i]] + f[i]);                    }                }            }            else {                for(int j = 1; j <= 200000 + s[i]; j++) {                    if(dp[j - s[i]] > -INF) {                        dp[j] = max(dp[j], dp[j - s[i]] + f[i]);                    }                }            }        }        int ans = 0;        for(int i = 100000; i <= 200000; i++) {            if(dp[i] > 0)                ans = max(ans, dp[i] + i - 100000);        }        printf("%d\n", ans);    }    return 0;}
#include <iostream>  #include <cstdio>  #include <cstring>  using namespace std;  const int MAX = 100 * 2000 + 10;  int ts[MAX];    // total_smart    // dp[i][j] meas with cow i, total_funness j, we have maxium sum dp[i][j]   // dp[i][j]中的 j 和 tf[j]不一样,j不知道要减去多少个 1000才能得到实际的total_funness   int dp[MAX];  struct cow  {      int s, f;  }cows[105];  int max(int a, int b) { return (a > b) ? a : b; }  int main(int argc, char const *argv[])  {      //freopen("in.txt", "r", stdin);      int n;      while(cin >> n)      {          // sum为ts的最大值          int sum = 0;          for(int i = 1; i <= n; ++ i)          {              cin >> cows[i].s >> cows[i].f;              cows[i].s += 1000;              sum += cows[i].s;          }          // 初始化为负无穷大          memset(dp, -0x3f, sizeof(dp));          dp[0] = 0;          memset(ts, 0, sizeof(ts));          for(int i = 1; i <= n; ++ i) {              for(int j = sum; j >= cows[i].s; -- j) {                  int temp = dp[j - cows[i].s] + cows[i].s - 1000 + cows[i].f;                  if (dp[j] < temp) {                      dp[j] = temp;                      ts[j] = ts[j - cows[i].s] + cows[i].f;                    }              }          }          // 找出符合 ts >= 0 和 tf >= 0 的最大值          int ans = 0;          for(int i = 0; i<= sum; ++ i)          {                 if(dp[i] > ans && ts[i] >= 0 && (dp[i] - ts[i]) >= 0) {                  ans = dp[i];              }             }          cout << ans << endl;          }      return 0;  }  
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 戒母乳胸胀的疼怎么办 断奶孩子晚上哭的厉害怎么办 喜欢咬指甲的人怎么办? 成年了还咬指甲怎么办 戒奶乳房有硬块怎么办 戒奶七天有硬块怎么办 两岁宝宝喘气粗怎么办 两岁宝宝断不了奶怎么办 两岁宝宝不愿意喝奶粉怎么办 吃母乳不愿意吃奶粉怎么办 母乳宝宝不愿意喝奶粉怎么办 宝宝断母乳不喝奶粉怎么办 9个月宝宝不会爬怎么办 孩子五年级学习成绩差该怎么办 孩子临近中考学习成绩很差该怎么办 初中生成绩不好家长该怎么办 成绩差该怎么办贴吧 宝宝只会匍匐爬怎么办 一年级的孩子数学不好怎么办 小学一年级孩子数学不好怎么办 孩子上一年级数学太差怎么办 智商低情商也低怎么办? 孩子字写得很大怎么办 孩子拿笔重 写字太黑 怎么办 孩子语文成绩好数学不行怎么办? 孩子现在二年级特别叛逆怎么办 孩子又笨又蠢怎么办 四年级孩子数学计算能力差怎么办 孩子四年级数学理解能力差怎么办 孩子小学四年级数学很差怎么办 孩子做作业太慢怎么办 小学三年级数学成绩差怎么办 初一数学考了3分怎么办 初二物理太差该怎么办 三年级孩子字写的差怎么办 小学三年级数学才考86怎么办 小孩子一发脾气就打妈妈怎么办 孩子做错事不肯道歉怎么办 小孩写作业注意力不集中怎么办 六年级的数学下册差怎么办 一年级小孩做作业慢怎么办