[USACO]奶牛会展(背包)

[USACO]奶牛会展

题目背景

奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行

了面试,确定了每头奶牛的智商和情商。

题目描述

贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。

输入输出格式

输入格式:

? 第一行:单个整数N,1 ≤ N ≤ 400

? 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,表示第i 头奶牛的智商和情商,?1000 ≤ Si; Fi ≤ 1000

输出格式:

输出格式

? 单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出0

输入输出样例

输入样例#1:

5
-5 7
8 -6
6 -3
2 1
-8 -5

输出样例#1:

8

说明

选择第一头,第三头,第四头奶牛,智商和为?5+6+2 = 3,情商和为7?3+1 = 5。再加

入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的

被绿题支配的恐惧??? 最开始看到题目是懵逼的,之后看了题解才明白。将智商和情商分别看作容量和价值来做01背包。
\(F[i]\)表示当智商总和为\(i\)时,情商的最大值。
\[F[i]=max(F[i-a[k]]+b[k])\]
但是有一点我们需要注意,在状态转移的过程中,智商和情商是允许为负数的,所以我们为了考虑到这种情况,将智商往右移\(sa\)个单位。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int read()
{
    int x=0,w=1;char ch=getchar();
    while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*w;
}
int dp[800010],a[410],b[410];
int main()
{
    int sa=0,ans=0;
    int n=read();
    for(int i=1;i<=n;i++)
    {
        a[i]=read();b[i]=read();
        if(a[i]>0) sa+=a[i];
    }
    sa=sa*2;
    memset(dp,-0x3f,sizeof(dp));
    dp[sa/2]=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>=0)
            for(int j=sa;j>=a[i];j--)
            {
                dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
            }
        else
            for(int j=0;j<=sa-a[i];j++)
            {
                dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
            }
    }
    sa/=2;
    for(int i=0;i<=sa;i++)
    {
        if(dp[i+sa]>=0)//这句判断一定不能忘记了
        ans=max(ans,i+dp[i+sa]);
    }
    cout<<ans;
}

原文地址:https://www.cnblogs.com/lsgjcya/p/9183448.html

时间: 2024-10-02 10:06:03

[USACO]奶牛会展(背包)的相关文章

洛谷P2340 奶牛会展

洛谷P2340 奶牛会展用下标表示智商,值表示情商 1 #include <bits/stdc++.h> 2 #define For(i,j,k) for(int i=j;i<=k;i++) 3 using namespace std ; 4 5 const int N = 411 ; 6 int n,m ; 7 int a[N],b[N],f[800011] ; 8 9 inline int read() 10 { 11 int x = 0 , f = 1 ; 12 char ch =

奶牛会展

题目背景 奶牛想证明它们是聪明而风趣的.为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行 了面试,确定了每头奶牛的智商和情商. 题目描述 贝西有权选择让哪些奶牛参加展览.由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零.满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值. 输入输出格式 输入格式: • 第一行:单个整数N,1 ≤ N ≤ 400 • 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,

【Luogu】P2340奶牛会展

题目链接 突发奇想可以用f[i]表示智商和为i的时候情商最大是多少.这样就变成了一个背包问题. 最后更新答案的时候从0到最大背包容量遍历,最后答案是最大的i+f[i]; 但是虽然答案只能从0到m里选,转移过程中是不能丢掉负数体积的.这是因为人家题目只说了要最后的智商和不能小于零,情商和不能小于零,没说中间不可以. 代码如下. #include<cstdio> #include<cctype> #include<cstring> #include<algorithm

USACO 奶牛食品(网络流)

题目大意: FJ的奶牛们只吃各自喜欢的一些特定的食物和饮料,除此之外的其他食物和饮料一概不吃.某天FJ为奶牛们精心准备了一顿美妙的饭食,但在之前忘记检查奶牛们的菜单,这样显然是不能不能满足所有奶牛的要求.但是FJ又不愿意为此重新来做,所以他他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. FJ提供了F (编号为1.2.-.F)种食品并准备了D (编号为1.2.-.D)种饮料, 他的N头牛(编号为1.2.-.N)都已决定了是否愿意吃某种食物和喝某种饮料.FJ想给每一头牛一种食品和一种饮料,使得尽可

题解 P2340 【奶牛会展】

此题搜索可以过!!! 看到此题,第一想法,是01背包,然而,作为一个蒟蒻,我怎么会打正解呢?,于是就开始打dfs! 想要完成此题,普通的搜索肯定是过不了的(不然要dp干嘛),所以,我们要考虑 剪枝 比较容易的,我们可以轻松想出来剪枝: (不吐槽名字我们还是好朋友...) 1.用数组guji[i]表示搜索到i时,不考虑智商,情商必须大于零的限制,之后能获得的最大智,情商之和.如果当前搜索到的智,情商之和加上guji[i]任然小于等于已经搜出来的ans,那么,当前的状态一定不是最优的(这属于最优性优

【题解】luogu p2340 奶牛会展

总结:1.智商从哪开始循环没想到. 2.将智商的正负分开讨论.负智商要用顺序,保证不会使一头牛多用. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 800005; 4 int dp[MAXN], n, iq[405], eq[405], maxx = -2000000; 5 int main() 6 { 7 memset(dp, -0x3f, sizeof(dp)); 8 dp[400000] = 0;

BZOJ 1666 Usaco 奶牛的数字游戏

1 #include <cstdio> 2 #include <algorithm> 3   4 int n; 5 int tot; 6   7 int main(){ 8     scanf("%d",&n); 9     while(n!=1){ 10         if(n%2!=0){ 11             n=n*3+1; 12             tot++; 13         } 14         else if(n%

USACO 奶牛排队

题目:给出一个只含有1,2,3的数字序列,问最少交换多少次才能将之变为递增数列. 解: 注意到只有1,2,3,我们只要将1,3交换到自己的应在位置上那么排序就已经完成了. 需要交换的有几种,记$a(x,,y)$表示x在应该是y的位置上的$a(i)$的个数,那么我们优先交换a(1,3)和a(3,1)里的数字,一次交换扳正两个位置,接下来要想扳正一个1或3的位置就必须要进行一次交换操作. 统计计算即可. 1 #include <iostream> 2 #include <cstdio>

从零开始的DP练习册

此文为博主原创,转载时请通知博主,并把原文链接放在正文醒目位置. 因为我确实把DP忘得一干二净...就当新学了.无解析无责任,只贴题目来源和AC代码. 1.数字三角形 记忆化搜索还是很容易想的,这个代码是我早期的代码orz 1 #include<iostream> 2 #include<cstdio> 3 //code by kamigen 4 using namespace std; 5 6 int num[1000][1000]; 7 8 int main() 9 { 10 i