经典问题: 有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;
    }

}