P2340牛展DP
\(N \)牛、すべての牛は、IQを持っている\(S [i]が\) EQ \(F [i]が\) 、その牛のいくつかのヘッドを選択する方法を求めているIQと最大のEQとEQとIQ非負の合計
\(N \ 400、^ 3 -10 \ sの10 ^ 3 \ \ [IN])
対処するのが難しいらしく、二次元、我々は最後のボリュームのステータス更新を横断、IQ、01リュックサックのEQ値の音量をやって、一次元考えることができますがへの否定ではありません。
ボリュームがそう当社の全体的なプラス、マイナスであってもよいことに留意する必要があります\(400 \ times1000 \) ;負のボリュームは、バックパックを横断するとき、それは一次元圧縮されているように、逆方向移動量になってますが、ここでは負であるので、正の配列であることがされトラバーサル(状態はそうでないカバーされる前に)
また、バックパックのボリュームは、ここでは単に初期値がAllに設定されているように充填される-INF
代わりに、\(0 \)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline int read(){
char ch=getchar();int s=0;
bool isf=0;
while((ch<'0'||ch>'9')&&(ch!='-')) ch=getchar();
if(ch=='-'){ch=getchar();isf=1;}
while(ch>='0'&&ch<='9') s=s*10+(ch^'0'), ch=getchar();
if(isf) return -s;
return s;
}
#define MAXN 404
#define BASE 400*1000
int n;
int s[MAXN],f[MAXN];
int dp[800008];
int main(){
n=read();
int mxs=0;
for(int i=1;i<=n;++i) s[i]=read(),f[i]=read(),mxs+=s[i];
memset(dp, -0x3f, sizeof dp);
dp[BASE]=0;
for(int i=1;i<=n;++i){
if(s[i]>=0)
for(int j=BASE+mxs;j>=s[i];--j)
dp[j]=max(dp[j], dp[j-s[i]]+f[i]);
else
for(int j=s[i];j<=BASE+mxs;++j)
dp[j]=max(dp[j], dp[j-s[i]]+f[i]);
}
int ans=0;
for(int i=BASE;i<=mxs+BASE;++i)
if(dp[i]>=0)
ans=max(ans, i-BASE+dp[i]);
printf("%d\n", ans);
return 0;
}