必殺ゲージ - ナップザック問題

ナップザック問題は、ルックバックパックに9つのストレスを取ることができます

0-1バックパック

https://www.luogu.org/problemnew/show/P1048

検索コードのメモリ:

/**
* memory search
* P1048
* @author Hongchuan CAO
*/

#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstdio>

using namespace std;

int val[110][2];
int mem[110][1010];

int t,m;
int result = 0;

void clear(){
    for(int i=0;i<110;i++){
        for(int j=0;j<1010;j++){
            mem[i][j] = -1;
        }
    }
}

void get_data(){
    scanf("%d%d",&t,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d",&val[i][0],&val[i][1]);
    }
}

int dfs(int index,int lleft){
	//if searched, return directly
    if(mem[index][lleft]!=-1) return mem[index][lleft];
	//return 0 if index>=m
    if(index>=m) return 0;
    int chose=0,uchose=0;
	//divide into two condition (choose or not)
    uchose = dfs(index+1,lleft);
    if(lleft>=val[index][0]){
        chose = dfs(index+1,lleft-val[index][0])+val[index][1];
    } 
    //add to memory array
    return mem[index][lleft] = max(uchose,chose);
}

int main(){
    clear();
    get_data();
    printf("%d\n",dfs(0,t));
    return 0;
}

DPコード:
状態遷移方程式:
F [ ] [ J ] = メートル A バツ F [ - 1 ] [ J ] F [ - 1 ] [ J - ワット [ ] ] + V [ ] F [I] [J] = MAX(F [I-1]〜[J]、F [I-1] [JW [I] + V [i])と
状態以来 状態であり、 - 1 I-1 変換が来るので、一次元アレイの二次元アレイに圧縮することができます。

このステータスコード F [ ] [ J ] F [i]は[J] 第として ハーブの支出時間 J J 時の最大値(以下Jなければならないこの時点で費やされた時間は、Jに等しくなくてもよい)
ので、すべての値が0に初期化されます

/**
 * DP : dp[j] = max(dp[j],dp[j-w[i]]+val[i]);
 * p1048
 * @author Hongchuan CAO
 */


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>

using namespace std;

const int INF = 1e8;
int t,m;
int dp[1010];
int stat[110][2];

//all inital is zero which is important

void get_data(){
    scanf("%d%d",&t,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&stat[i][0],&stat[i][1]);
    }
}

void solve(){
    for(int i=1;i<=m;i++){
        for(int j=t;j>=stat[i][0];j--){
            dp[j] = max(dp[j],dp[j-stat[i][0]]+stat[i][1]);
        }
    }
    printf("%d\n",dp[t]);
}

int main(){
    get_data();
    solve();
    return 0;
}

別のアプローチ
状態 F [ ] [ J ] F [i]は[J] 第として ハーブ過ごす時間だけとして J J 時の最大値

初期化時にのみ[0] [0]はゼロであるDP、他の値が負の無限大のある事実、この場所は、負の無限大はまた、このようなに直面して、特別な裁判官することができ、正確にポイントがマイナスされていることができない人を作ることです点は、状態遷移方程式をスキップすることができます。
だから、最終的には、最終的な結果ではありません D p [ n ] [ m ] DP [n]は[M] が、 d p [ n ] [ 0... m ] DP [n]は[0 ... M] の最大値。(すべての結果であるため、単に時間の最大値を埋めるために)

/**
 * DP : dp[j] = max(dp[j],dp[j-w[i]]+val[i]);
 * p1048
 * @author Hongchuan CAO
 */


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>

using namespace std;

const int INF = 1e8;
int t,m;
int dp[1010];
int stat[110][2];

void clear(){
    for(int i=1;i<1010;i++) dp[i] = -INF;
    dp[0] = 0;
}

void get_data(){
    scanf("%d%d",&t,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&stat[i][0],&stat[i][1]);
    }
}

void solve(){
    int maxx = -1;
    for(int i=1;i<=m;i++){
        for(int j=t;j>=stat[i][0];j--){
            dp[j] = max(dp[j],dp[j-stat[i][0]]+stat[i][1]);
        }
    }

    for(int i=0;i<=t;i++){
        maxx = max(maxx,dp[i]);
    }
    printf("%d\n",maxx);
}

int main(){
    clear();
    get_data();
    solve();
    return 0;
}

フル・バックパック

https://www.luogu.org/problemnew/show/P1616

複数のバックパック

https://vjudge.net/problem/POJ-1742

おすすめ

転載: blog.csdn.net/baidu_41560343/article/details/92739976