Luogu P2340 [USACO03FALL]Cow Exhibition G

Face questions

Description of the meaning of problems

For \ (n-\) th items, each item has two attributes (an integer), selected from a plurality of items required, so that the sum of any two properties and a property of the maximum and not less than \ (0 \)

solution

The meaning of problems like backpacks, complexity \ (W = 400 \ times 1000 \) is also in line \ (O (nW) \) , will be considered by thought backpack

Trick, a property selected from the weight, the other attribute value,

However, because of the presence of a negative weight, so when using the C ++ will the size of the array to open to \ (800,000 \) , the subscript \ (400,000 \) represents a weight of \ (0 \) , \ (400,000 \) The following are negative, the above is a positive number

Two such attributes as well as their own and worked out and will be able to clear

The next problem is to do a backpack

For when the weight is a positive number, the same as ordinary backpack to 01, from large to small updates

When the weight is negative, because subtracting a negative number is equivalent to adding a positive number, so do the backpack from the smallest to the big time update

Core code:

    for(int i=1;i<=n;++i) {
        if(w[i]>=0) {                                            // 重量为正数
            for(int j=800000;j>=w[i];--j)                        // 从大往小枚举
                f[j] = max(f[j],f[j-w[i]]+v[i]);
        } else {
            for(int j=0;j<=800000+w[i];++j) {                    // 重量为负数
                f[j] = max(f[j],f[j-w[i]]+v[i]);                 // 从小往大枚举
            }
        }
    }

The final answer is

\ [\ Max_ {400000 \ leq i \ leq 800000} f_i + i-400000 \ \ (f_i \ geq 0) \]

The final code:

#include<bits/stdc++.h>
using namespace std;
char ch;int fl;
template<typename T>
inline T redn(T &ret) {                                        // 快读
    ret=0,fl=1,ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-')fl=-1;ch = getchar();}
    while(ch>='0'&&ch<='9') {ret=ret*10+ch-'0';ch=getchar();}
    return ret=ret*fl;
}
int n;
int w[404],v[404],f[400000<<1+1];
int main() {
    redn(n);
    for(int i=1;i<=n;++i) redn(w[i]),redn(v[i]);
    memset(f,128,sizeof f);
    f[400000] = 0;
    for(int i=1;i<=n;++i) {
        if(w[i]>=0) {                                            // 重量为正数
            for(int j=800000;j>=w[i];--j)                        // 从大往小枚举
                f[j] = max(f[j],f[j-w[i]]+v[i]);
        } else {
            for(int j=0;j<=800000+w[i];++j) {                    // 重量为负数
                f[j] = max(f[j],f[j-w[i]]+v[i]);                 // 从小往大枚举
            }
        }
    }
    int ans = 0;
    for(int i=400000;i<=800000;++i) if(f[i]>=0) ans = max(ans,f[i]+i-400000);
    printf("%d",ans);
}

Guess you like

Origin www.cnblogs.com/Ax-Dea/p/12571609.html