我的学习记录-01背包(背包九讲)

我的学习记录-01背包(背包九讲)

文章目录

  • 我的学习记录-01背包(背包九讲)
  • 前言
  • 一、题目引入- Bone Collector
  • 二、学习和解决(01背包模板分析)
    • 引入
    • 1.优化前
    • 2.优化后
  • 总结


前言

你好!这是我的第一篇CSDN的博客,我是一名新手,是一名在校大学生,我希望能在学习中不断的进步,有着不断的热情大步向前,如果有什么不对的地方欢迎指出!


提示:以下是本篇文章正文内容

一、题目引入- Bone Collector

题目:
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

输入:
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

输出
One integer per line representing the maximum of the total value (this number will be less than 231).

样例
1
5 10
1 2 3 4 5
5 4 3 2 1

14

二、学习和解决(01背包模板分析)

引入

这是一道十分基础的背包题目,最重要的是要推出合适的动态转移方程,对于这道题我们可以发现背包装这个i物品是不是最优解只于 ii-1 有关,所以最开始的代码我们是用一个二维数组dp[n][m]来表示最优,行表示这个物品序列对应的列表示背包大小。

这里有一个初始化优化细节:
1.如果是不要求装满背包:

memset(dp, 0, sizeof(dp));
//注意这个地方初始化为0;

2.如果是要求装满背包:

memset(dp, -inf, sizeof(dp));
//初始化为一个负数

1.优化前

代码如下(示例):

for(int i = 1; i <= n; i ++)
{
	for(int j = 1; j <= m; j++)
	{
		dp[i][j] = dp[i-1][j];
		if(w[i]<=j)
			dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+c[i]);
	}
}

2.优化后

代码如下(示例):

for(int i = 1; i <= n; i ++)
{
	for(int j = m; j >= w[i]; j--)
	{
		dp[j] = max(dp[j], dp[j-w[i]]+c[i]);
	}
}

上面对二维的数组进行了处理,注意:第二个for寻魂里面是倒序循环。


总结

这是一道十分简单的背包九讲题里面的第一种01背包,这是我的第一篇博客所以我用了很多特定的模板而且没有很多自己的风格。上面的例题我WA了6次,差点直接自闭,后面仔细看了题目,我居然把输入里面的volue和volume看反了,所以一直WA(我是傻逼

下面我把自己的AC代码贴上:(头文件很长

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1010;

ll dp[N];
int n, m, t;
int w[N], c[N]; 

int main (void)
{
	cin >> t;
	while(t--)
	{
		memset(dp, 0, sizeof(dp)); 
		cin >> n >> m;
		for(int i = 1; i <= n; i++) cin >> c[i];
		for(int i = 1; i <= n; i++)	cin >> w[i];
		
		for(int i = 1; i <= n; i ++)
		{
			for(int j = m; j >= w[i]; j--)
			{
					dp[j] = max(dp[j], dp[j-w[i]]+c[i]);
			}
		}
		
//		int res = 0;
//		for(int i = 1; i <= m; i++) res = max(res, dp[i]);
//		cout << res << endl;
		
		cout << dp[m] << endl;
		
		
//		memset(w, 0, sizeof(w));
//		memset(c, 0, sizeof(c));  
	}
	return 0;
}
//powered by xiaodezi

你可能感兴趣的:(c++,动态规划)