【菜鸟er】动态规划_01背包

#include <bits/stdc++.h>
#define MAX_N 1000
using namespace std;

int v[MAX_N],w[MAX_N];
int dp[100][100];
int n;
int wmax,vmax;

int main()
{
    //输入
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>w[i]>>v[i];
    }
    cin>>wmax;
    /*确定子问题:
        目的是得到最大价值,操作是要不要把第i件物品放到背包中?
    */
    /*确定dp[][]含义:
        dp[i][j]:   i:前i件物品参与了操作;
                    j:体积为j的背包;
                    dp[][]:在ij情况下的最大价值
                    ==:前i件中若干个物品放入体积为j的背包中的最大价值。

    */
    /*调整初始状态:(边界处理)
        x为任意有效值
        dp[0][x] = 0; //前0个物品放入最大支持x的背包中总价值永远是0
        dp[x][0] = 0; //背包大小为0,总价值永远为0;
    */
    /*最激动人心的地方:状态转移方程的确定
        1.同调整初始状态
        2.
            如果:背包体积j小于前i个物体之和
                背包装不下第i个物体了,此时总价值仍然为j-1时的价值
            否则:{
                //为了体积V的背包中物体总价值最大化,
                //第i件应该放入背包中吗?

                max(不放第i件,放第i件但是有空间减小的代价)
                //正是因为空间减小了,才能找到以前的值,才能比较

            }

            代码实现:
            if( j < w[i] ){
                f[i][j] = f[i-1][j];
            }
            else {
                f[i][j] = max( f[i-1][j] , f[i-1][j-w[i]]+v[i] );
            }

    */

    //刚出生哦
    /*//初始化的时候已经全部为0,不用再次操作
    for(int i = 0;i<n;i++){
        dp[i][0]=0;
        dp[0][i]=0;
    }*/
    //人家dp超简单的
    for(int i = 0;i<n;i++){
        for(int j = 0;j<=wmax;j++){
            if( j<w[i] ){
                dp[i+1][j] = dp[i][j];
            }
            else{
                dp[i+1][j] = max(dp[i][j],dp[i][j-w[i]]+v[i]);
            }

        }

    }
    //输出记忆化数组,这里为了输出多一点数据
    int print_max = wmax>n ? wmax+1 : n+1;
    for(int i = 0;i<print_max;i++){
        for(int j = 0;j<print_max;j++)
            cout<<dp[i][j]<<" ";
        cout<<endl;
    }

    cout<<dp[n][wmax]<<endl;

    //拓展:如果实现输出选择哪一个,把max()函数展开成一个if()即可;
    return 0;
}
/**
n个物品,重量用w表示,价值用v表示,
从中挑选总重量不大于wmax的物品,
求能挑出的最大值vmax;
*/
/*
data:
4
2 3
1 2
3 4
2 2
5
print:
7
*/

阅读更多

没有更多推荐了,返回首页