zoukankan      html  css  js  c++  java
  • 洛谷 P2340 [USACO03FALL]Cow Exhibition G 题解

    题目链接

    1.题外话

    咕咕咕

    2.解题意

    咕咕咕,比较容易理解,智商情商需要捆绑在一起。

    3.找思路

    每一个奶牛都只包含两种情况:选, 不选。并且很明显这不是一个完全背包。

    考虑套一套01背包的板子:每个奶牛都有两个参数:智商,情商。在01背包板子中,每一个物品都有两个参数:体积,价值。

    于是,第一种做法也就浮现而出:把智商设为体积,把情商当做价值,跑01背包。跑完后枚举一下智商大小,加上当前智商状态值所对应的的最大情商,取max即可。

    按理说是可以过的。但是偏偏有几个奶牛不是智商捉急负数,就是情商要命负数,再不就是歪比哇卜双负数

    对于智商为负数的情况,众所周知数组下标不能有负数,于是我们可以将数组往右平移一整个范围。这样保证即使智商全取负数中的最小值,也依然>=0。具体表现在代码中,就是数组多开一倍,枚举智商值的j增大一倍即可。

    j对于情商为负数的情况。由于一维的01背包是从大到小枚举以保证每个物品只选一次。如果是负数,那么减去负数得正数,你将获得从小往大里枚举的效果(完全背包)。每个牛牛是独一无二的所以我们不能多次枚举,很明显不符合题意。

    解决方法是遇到负数,你人为的把枚举的顺序倒过来即可。目的是保证每一个牛仅被选一次。,注意一下枚举智商的j的范围。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define N 407
    using namespace std;
    inline int read()
    {
        int ans=0;
        char ch=getchar(),last=' ';
        while(ch>'9'||ch<'0')last=ch,ch=getchar();
        while(ch>='0'&&ch<='9')ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
        return last=='-'?-ans:ans;
    }
    struct cow{
        int iq,eq;
    }cow[N];
    int n,f[800007],maxn;
    int main(){
        scanf("%d",&n);
        memset(f,-0x3f,sizeof(f));
        f[400000]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&cow[i].iq,&cow[i].eq);
        }
        for(int i=1;i<=n;i++)
        {
            if(cow[i].iq>=0)
            {
                for(int j=800000;j>=cow[i].iq;j--)
                    f[j]=max(f[j],f[j-cow[i].iq]+cow[i].eq);
            }
            else
            {
                for(int j=0;j<=800000+cow[i].iq;j++)
                    f[j]=max(f[j],f[j-cow[i].iq]+cow[i].eq);
            }
        }
        for(int i=400000;i<=800000;i++)
        {
            if(f[i]>=0)
            maxn=max(maxn,f[i]+i-400000);
        }
        printf("%d",maxn);
    }

    完结撒花。

    祝各位NOIP2020 RP++

  • 相关阅读:
    使用iconv编程进行字符集转换
    Unity3D学习之路 C#学习笔记(一)
    跨平台的游戏客户端Socket封装
    TCP长连接与短连接的区别
    C++中的long long和__int64类型
    基于cocos2dx的游戏客户端优化
    Android NDK带来什么
    strcpy_s与strcpy的比较
    英文字母和中文汉字在不同字符集编码下的字节数
    socket的read和recv函数的区别
  • 原文地址:https://www.cnblogs.com/lbssxz/p/13644030.html
Copyright © 2011-2022 走看看