经典背包问题
换汤不换药的题目:给你一个背包,里面容量有限,然后给你几块宝石,每块宝石的体积和价值不一样,问你背包里面装的宝石的最大价值为多少。
背包容量 W,n块宝石
for( int i = 1; i <= n i++ )
w[i],v[i] 重量,价值
数据:
1
20 4
6 2
5 3
2 4
9 4
思路:其实就是暴力,将所有的可能都尝试(但是会记录,记录相应容量能得到的最大价值),
比如尝试放入
6 2 (体积为6,价值为2),所有6之前的相应容量,都记录了价值2(因为是第一次,所以没有出现叠加)
5 3 ,这里5-20的相应容量的值发生变化( 10-5没有出现叠加,11-20出现叠加,这一步很关键,
为什么能叠加? 看(前面代码也需要看)dp[j] = max( dp[j],dp[ j - w[i] ] ) ,只有在 j >= 11的时候才能叠加,表示容量大于等于11时能放入这两块宝石。当然如果对应容量出现更大的价值也需要记录更大值。
为什么没有出现叠加就需要解释了。
)
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
int t;
int W,n;
int w[1000];
int v[1000];
int dp[1000];
cin>>t;
while( t-- ){
cin>>W>>n;
memset(dp,0,sizeof(dp));
for( int i = 1 ; i <= n ; i ++ ){
cin>>w[i]>>v[i];
}
for( int i = 1 ; i <= n ; i ++ ){
for( int j = W ; j >= w[i] ; j -- ){ //20 // 5 3
dp[j] = max( dp[j] , dp[ j - w[i] ] + v[i] );
}
// for( int j = W ; j >= w[i] ; j-- ){
// cout<<j<<" "<<dp[j]<<" |";
// }
// cout<<endl;
}
cout<<dp[W]<<endl;
}
}