动态规划(三)神奇的口袋||0-1背包问题


代码实现:

递归实现

#include<iostream>
using namespace std;
int a[30];
int N;
int Ways(int w, int k)
{//从前k种物品中选择一些,凑成体积w的做法物品
	if (w == 0)
		return 1;//w=0,一个都不选,只有一种选法
	if (k <= 0)
		return 0;//没有选择方法
	return Ways(w, k - 1) + Ways(w - a[k], k - 1);//不选第k种物品的选法+选了第k种物品的选法
}
int main()
{
	cin >> N;
	for (int i = 1; i <= N; i++)
		cin >> a[i];
	cout << Ways(40, N);
	return 0;
}

动规解法:

#include<iostream>
using namespace std;
int a[30];
int N;
int Ways[40][30];//Ways[i][j]表示从前j种物品里凑出体积i的方法数
int main()
{
	cin >> N;
	memset(Ways, 0, sizeof(Ways));
	for (int i = 1; i <= N; i++)
	{
		cin >> a[i];
		Ways[0][i] = 1;
	}
	Ways[0][0] = 1;
	for (int w = 1; w <= 40; w++)
	{
		for (int k = 1; k <= N; k++)
		{
			if (w - a[k] >= 0)
				Ways[w][k] = Ways[w][k - 1] + Ways[w - a[k]][k - 1];//不取第k种物品的做法+取第k种物品的做法
			else
				Ways[w][k] = Ways[w][k - 1];//无法取第k种物品
		}
	}
	cout << Ways[40][N];
	cin >> N;
	return 0;
}

例 0-1背包问题



解题思路




要实现滚动数组的思想必须从右向左赋值,

代码实现:

#include<iostream>
#include<algorithm>
using namespace std;
const int N=3500;
const int M = 12880;
int W[N], D[N], Rate[M];
int main()
{
	int n, m;
	cin >> n>>m;
	memset(Rate, 0, sizeof(Rate));
	for (int i = 0; i < n;i++)
	{
		cin >> W[i] >> D[i];
	}
	for (int i = 0; i < n; i++)
	{
		for (int j = m; j >= W[i]; j--)
		{
				Rate[j] = max(Rate[j - W[i]] + D[i], Rate[j]);
		}
	}
	cout << Rate[m] << endl;
	cin >> n;
	return 0;
}

下面是利用二维数组完成:

#include<iostream>
#include<algorithm>
using namespace std;
const int N=3500;
const int M = 12880;
int W[N], D[N], Rate[N][M];
int main()
{
	int n, m;
	cin >> n>>m;
	memset(Rate, 0, sizeof(Rate));
	for (int i = 1; i <=n;i++)
	{
		cin >> W[i] >> D[i];
	}
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j < W[i]; j++)
			Rate[i][j] = Rate[i - 1][j];
		for (int j = W[i]; j <= m;j++)
		{
			Rate[i][j] = max(Rate[i - 1][j - W[i]] + D[i], Rate[i - 1][j]);//后i种商品组成质量j的最大价值=max(有第i种商品参与的最大值,无第i种商品参与的最大值)
		}
	}
	cout << Rate[n][m] << endl;
	cin >> n;
	return 0;
}


















猜你喜欢

转载自blog.csdn.net/qq_42020563/article/details/80649095