之前揹包問題學了忘學了忘= =是太笨了。
題目
許多年前,在泰迪的家鄉,有一個人被稱爲“骨收集者”。這個人喜歡收集各種骨頭,例如狗,牛的骨頭,他也去了墳墓……
骨頭收集者有一個大袋子,裏面裝有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;
}
如果有說錯的地方,歡迎指錯~~
歡迎來我個人博客玩(交換友鏈)