完全背包问题:最基础解法 一般动态规划

完全背包问题:最基础解法 一般动态规划

约定

dp[ i ][ j ] 表示在 1~i 个物品中,使用容量为 j 的背包拿取得到的最大值(不管是不是完全背包)

思路

01背包状态转移方程:

dp[ i ][ j ] = max( dp[ i-1 ][ j ] , dp[ i-1 ][ j - cost[ i ] ])

完全背包规定了物品不止可以选取一次,那么其实状态从 0,1变成了 0,1,2,… j / cost[ i ] ,只要在这些状态中找最大值即可,但是时间复杂度非常高

题目描述

设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为m,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于m,而价值的和为最大。

输入

第一行:两个整数,m(背包容量,m≤200)和 n(物品数量,n≤30);

第2…Nn1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

输出

仅一行,一个数,表示最大总价值。

样例输入

10 4

2 1

3 3

4 5

7 9

样例输出

12

#include <iostream>

using namespace std;

#define MAXLEN 114
#define MAXCOST 1145 
int m, n;
int value[MAXLEN];
int cost[MAXCOST];
int dp[MAXLEN][MAXCOST];

int main()
{
	cin>>m>>n;
	
	for(int i=1; i<=n; i++)
	{
		cin>>cost[i]>>value[i];
	}	
	
	// 初始化 计算取前1个物品的最大值 
	for(int i=0; i<=m; i++)
	{
		if(i >= cost[1])
		{
			dp[1][i] = value[1];
		}
		else
		{
			dp[1][i] = 0;
		}
	}
	
	for(int i=2; i<=n; i++)
	{
		for(int j=0; j<=m; j++)
		{
			int max = dp[i-1][j];
			for(int k=0; k<=j/cost[i]; k++)
			{
				if(j >= k*cost[i])
				{
					int res = dp[i-1][j-k*cost[i]] + k*value[i];
					if(res > max)
					{
						max = res;
					}
				}
			}
			dp[i][j] = max;
		}
	}
	
	cout<<dp[n][m]<<endl;
	
	return 0;
}
发布了38 篇原创文章 · 获赞 1 · 访问量 482

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104073113