经典问题: 有n个物品,分别价值为value,重为volume, 放入一个m的背包 (保证放满) 问如何使得价值最大
分析: 首先从最后那个状态来看 dp[i][j]=max(dp[i-1],dp[i-1][ j-vo[i] ]+va[i]),起始状态显然是dp[0][j]=0,有了起始状态 我们便可以一次一次的转移到最后的最大值
对于一些细节上的解释:枚举j(重量)时有些j 并不会用到,也不会产生影响(遇到两个重复出现时,会取最大的),因为各个情况都要考虑到所以每个j都考虑,也有可能数据太大了此时就需要离散化 ,只枚举必须的部分。
因为状态转移是根据i转(j两两之间没有关系)而i 也就这个用前一个 在往后推 最前面的就用不着了所以可以用滚动数组滚去一个维度,比如斐波那契数列。 同时j从高向低走保证不会刷新后面要用到的数
初始状态和末状态都可以 由i去判定
ac代码:
#include<bits/stdc++.h>
using namespace std;
struct node {
int vo,va;
}bone[1002];
int dp[1002];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>bone[i].va;
for(int i=0;i<n;i++)
cin>>bone[i].vo;
for(int i=0;i<=m;i++) dp[i]=0;
for(int i=0;i<n;i++)
for(int j=m;j>=bone[i].vo;j--)
dp[j]=max(dp[j],dp[j-bone[i].vo]+bone[i].va);
cout<<dp[m]<<endl;
}
}

京公网安备 11010502036488号