P2340牛展示DPバックパック

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

おすすめ

転載: www.cnblogs.com/santiego/p/11839506.html