hdu 3127

1、在贴代码之前,有几点是需要知道的

F[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。那么对于第i种物品的出现,我们对第i种物品放不放入背包进行决策。如果不放那么F[i][j]=F[i-1][j];如果确定放,背包中应该出现至少一件第i种物品,所以F[i][j]种至少应该出现一件第i种物品,F[i][j]=F[i][j-C[i]]+W[i]。为什么会是F[i][j-C[i]]+W[i]?因为F[i][j-C[i]]里面可能有第i种物品,也可能没有第i种物品。我们要确保F[i][j]至少有一件第i件物品,所以要预留C[i]的空间来存放一件第i种物品。

 

2、

完全背包与01背包不同之处在于,每件物品的数量都是无限的。

在处理的时候:01背包是后面的前面dp, 完全背包是从前面到后面dp

 

3、以下是hdu 3217 的代码:

/*
 * 3217.cpp
 *
 *  Created on: 2013年7月29日
 *      Author: Administrator
 */

#include <iostream>

__int64 dp[1100][1100];
// __int64用于表示64位整数
using namespace std;

const int Max = 20;

struct Two_CostPackage {
	int x;
	int y;
	int val;
} p[Max];//用来存储三角形可能的种类

int main() {

	int i, j, k, t, xi, yi, n;

	cin >> t;

	while (t--) {

		cin >> n >> xi >> yi;

		for (i = 0; i < n; ++i) {
			cin >> p[i].x >> p[i].y >> p[i].val;
		}

		memset(dp, 0, sizeof(dp));

		for (j = 1; j <= xi; ++j) {//j是用来标记长度的变量
			for (k = 1; k <= yi; ++k) {//k是用来标记宽度的变量
				for (i = 0; i < n; ++i) {

					int x = p[i].x;
					int y = p[i].y;
					int val = p[i].val;

					if (j >= x && k >= y) {//如果j大于长x,k大于宽y(及存在符合条件的矩形)
						dp[j][k] = max(dp[j][k],
								max(dp[j - x][y] + dp[j][k - y],
										dp[j - x][k] + dp[x][k - y]) + val);
					}

					/**
					 * 交换长x和宽y,实现第二种切割方式.
					 * x,y是题目中其中一种指定三角形的长和宽.
					 */
					swap(x, y);

					if (j >= x && k >= y) {
						dp[j][k] = max(dp[j][k],
								max(dp[j - x][y] + dp[j][k - y],
										dp[j - x][k] + dp[x][k - y]) + val);
					}
				}
			}
		}


		cout<<dp[xi][yi]<<endl;
	}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气的东哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值