洛谷 P2340 USACO03FALL Cow Exhibition G

2025-02-13T17:21:39

url: https://www.luogu.com.cn/problem/P2340

tag:
动态规划,背包,USACO, 2003

思路:
可以转化为01背包问题来做,因为每个奶牛都只有选和不选两种状态。对于背包问题,需要考虑三个属性,一个是背包容量,一个是体积,还有一个是价值。在这道题中,iq和eq是等价的属性,所以可以一个当作体积,另外一个当作价值。关于背包容量,这道题没有显式的提出,不过我们可以用数据范围的最大值作为背包容量的最大值。因为iq和eq都是有正有负,所以就可以选择将数组向右扩大400000.因为转移方程是 f[j] = max(f[j], f[j - c[i].iq] + c[i].eq) 二维转变为一维。当是负数的时候,实际上 j - c[i].iq 是增大的,为了避免更新的对未更新的产生影响,所以需要变成从小到大遍历。

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 440;
struct cow {
    int iq, eq;
}c[N];
int f[N * 1000 * 2];
int n;
int res;
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++)
    {
        cin >> c[i].iq >> c[i].eq;
    }
    memset(f,-0x3f ,sizeof f);
    f[400000] = 0;
    for (int i = 1; i <= n; i ++)
    {
        if (c[i].iq >= 0)
        {
            for (int j = 800000; j >= c[i].iq; j --)
            {
                f[j] = max(f[j], f[j - c[i].iq] + c[i].eq);
            }
        }
        else
        {
            for (int j = 0; j <= 800000 + c[i].iq; j ++)
            {
                f[j] = max(f[j], f[j - c[i].iq] + c[i].eq);
            }
        }
    }
    for (int i = 400000; i <= 800000; i ++)
    {
        if (f[i] >= 0)
        res = max(res, f[i] + i - 400000);
    }
    cout << res << endl;
    return 0;
}
当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »