动态规划:0-1背包+完全背包,满包+二维dp优化成一维dp

1. 01背包

有N件物品和一个容量为W 的背包。放入第i(i=0,1,,,N-1)件物品耗费的容量是W[i],得到的价值是V[i]。求解将哪些物品装入背包可使价值总和最大。

dp[i][j]:可选物品为0~i,容量为j时的最大价值和
vector>dp(N,vector(W+1,0));
for(int i=1;i=w[i])
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//物品i不选/选
        else
            dp[i][j]=dp[i-1][j];
return dp[N-1][W];
//画二维图,可优化为一维dp
vectordp(W+1,0);
for(int i=0;i=0;--j)
        if(j>=w[i])//a
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        else 
            dp[j]=dp[j];//b
return dp[W];
//再优化a b
vectordp(W+1,0);
for(int i=0;i=w[i];--j)        
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
return dp[W];

 满包:W容量必须装满情况下的最大价值和

初始化时dp[i][0]=0,其他dp[i][j]都为INT_MIN,即可确保状态一定是从0转移过来的

dp[i][j]:可选物品为0~i,容量为j时的最大价值和
vector>dp(N,vector(W+1,INT_MIN));
for(int i=0;i=w[i])
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//物品i不选/选
        else
            dp[i][j]=dp[i-1][j];
return dp[N-1][W];
//画二维图,可优化为一维dp
vectordp(W+1,INT_MIN);
dp[0]=0;
for(int i=0;i=0;--j)
        if(j>=w[i])//a
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        else 
            dp[j]=dp[j];//b
return dp[W];
//再优化a b
vectordp(W+1,INT_MIN);
dp[0]=0;
for(int i=0;i=w[i];--j)        
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
return dp[W];

2. 完全背包

有N种物品和一个容量为W 的背包,每种物品都有无限件可用。放入第i(i=0,1,2,,,N-1)种物品的耗费的空间是w[i],得到的价值是v[i]。求解:将哪些物品装入背包,可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。

 转移方程不同(0-1背包dp[i][j]都由上一层dp[i-1][]推导得出,而完全背包dp[i][j]由dp[i-1][]和dp[i][]两层推导得出),导致二维降一维dp时遍历方向不同,画二维图可方便理解。

dp[i][j]:可选物品为0~i,容量为j时的最大价值和
vector>dp(N,vector(W+1,0));
for(int i=1;i=w[i])
            dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i]);//物品i不选/选
        else
            dp[i][j]=dp[i-1][j];
return dp[N-1][W];
//画二维图,可优化为一维dp
vectordp(W+1,0);
for(int i=0;i=w[i])//a
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        else 
            dp[j]=dp[j];//b
return dp[W];
//再优化a b
vectordp(W+1,0);
for(int i=0;i

 

你可能感兴趣的:(LeetCode)