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
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);
}