EOJ(动态规划)——1052. 0-1背包问题

单测试点时限: 2.0 秒

内存限制: 256 MB

已知 n 个物体 1,2,3,…,n 与一个背包。物体 i 的重量为 Wi>0,价值为 Pi>0 (i=1,2,…,n),背包容量为 M>0。

求在不超过背包容量的情况下,使得装进去的物体的价值最高。

输入
第一行为一个正整数 T,表示有几组测试数据。

每组测试数据的第一行为两个整数 n 和 M,0<n≤20,0<M<100000。

再下去的 n 行每行有两个整数 Wi,Pi,0<Wi,Pi<10000。

输出
对于每组测试数据,输出一行,只含一个整数,表示装进去物体的价值最高值。

样例
input
1
5 10
2 6
2 3
6 5
5 4
4 6
output
15

题目大意:

01背包。

题目解析:

第二次遇到01背包问题,这次算是完全弄明白了。
01背包核心代码:

		for(int i=1;i<=n;i++){
			for(int j=1;j<=M;j++){
				if(j<weight[i])
					dp[i][j]=dp[i-1][j];
				else{
					dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+price[i]);
				}
			}
		}

关键点:

  • dp[i][j]表示前i件物品,放入总空间为j的背包中,所能装下商品的最大价值。
  • for循环下标要从1开始而不是0开始,因为当i等于0时(即前0件商品)最大价值肯定为0,j等于0时(即总空间为0)最大价值肯定为0。
  • if(j<weight[i]) dp[i][j]=dp[i-1][j];//表示第i件商品的重量已经超出了总空间,所以肯定装不下,等于前i-1件商品在此空间下的总价值。
  • dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+price[i]);中的dp[i-1][j-weight[i]]+price[i]);表示把第i件物品放进去看看总价值为多少,其结果自然是物品i的价值加上前i-1件物品在总空间j-weight[i]中的最大总价值。跟不第i件物品做对比,看看谁大。

具体代码:

#include<iostream>
using namespace std;
#define MAXN 25
int weight[MAXN],price[MAXN];
int dp[MAXN][100005];//dp[i][j]表示前i件物品放入空间为j的最大价值 
int main()
{
    int T;
    cin>>T;
    while(T--){
    	int n,M;
    	cin>>n>>M;
    	for(int i=1;i<=n;i++)
    		cin>>weight[i]>>price[i];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=M;j++){
				if(j<weight[i])
					dp[i][j]=dp[i-1][j];
				else{
					dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+price[i]);
				}
			}
		}
		cout<<dp[n][M]<<endl;
	}
    return 0;
}
全部评论

相关推荐

09-29 11:19
门头沟学院 Java
点赞 评论 收藏
分享
11-15 18:39
已编辑
西安交通大学 Java
全村最靓的仔仔:卧槽,佬啥bg呢,本也是西交么
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务