Bone Collector-01揹包問題

之前揹包問題學了忘學了忘= =是太笨了。

題目

許多年前,在泰迪的家鄉,有一個人被稱爲“骨收集者”。這個人喜歡收集各種骨頭,例如狗,牛的骨頭,他也去了墳墓……
骨頭收集者有一個大袋子,裏面裝有V,而且在收集骨頭的過程中,很明顯,不同的骨骼具有不同的值和不同的體積,現在給定沿途的每個骨骼的值,您能否計算出骨骼收集器可以獲得的總值的最大值?

在這裏插入圖片描述

輸入格式

第一行包含整數T,即案例數。緊隨其後的是T個案例,每個案例三行,第一行包含兩個整數N,V(N <= 1000,V <= 1000),它們表示骨頭的數量和包的體積。第二行包含代表每個骨骼值的N個整數。第三行包含N個整數,代表每個骨骼的體積。

輸出格式

每行一個整數,代表合計的最大值(該數字將小於2 [sup] 31 [/ sup])。

輸入樣例

1 
5 10 
1 2 3 4 5 
5 4 3 2 1

輸出樣例

14

二維數組

問題分解:當前最優解,要麼包含第i種物品,要麼不包含第i種物品。
DP[i][j]表示前i個物品,揹包容量爲j的最優值。
狀態轉移方程爲:DP[i][j] = max(DP[i-1][j], DP[i-1][j-v[i]] + w[i]);

在這裏插入圖片描述

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
int dp[1100][1100],w[1100],v[1100];
int main(){
	scanf("%d",&t);
	while(t--){
		memset(dp,0,sizeof(dp));
		scanf("%d %d",&n,&m);
		for(int i=1;i<=n;i++) scanf("%d",&w[i]);		//骨骼值 
		for(int i=1;i<=n;i++) scanf("%d",&v[i]);		//體積 
		for(int i=1;i<=n;i++){
			for(int j=0;j<=m;j++){
				if(j>=v[i])
					dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
				else
					dp[i][j]=dp[i-1][j];		//保留之前的狀態 
			}
		}
		printf("%2d ",dp[n][m]);
	}
	return 0;
}

一維數組

和二維數組的差不多,不過就是把二維保存的值放到一維數組中
狀態轉移方程dp[j]=max(dp[j],dp[j-v[i]]+w[i]);,保證每輪和上輪可以用的比,保證3比2,2比1。

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
int dp[1100],w[1100],v[1100];
int main(){
	scanf("%d",&t);
	while(t--){
		memset(dp,0,sizeof(dp));
		scanf("%d %d",&n,&m);
		for(int i=0;i<n;i++) scanf("%d",&w[i]);     //骨骼值
		for(int i=0;i<n;i++) scanf("%d",&v[i]);     //體積
		for(int i=0;i<n;i++){
			for(int j=m;j>=v[i];j--){       
				dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
			}
		}
		printf("%d\n",dp[m]);
	}
	return 0;
}

如果有說錯的地方,歡迎指錯~~
歡迎來我個人博客玩(交換友鏈)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章