hdu2126(三维背包)

思路:显然的思路是前i个物品选j个花费k元的次数。

dp[i][j][k] = dp[i - 1][j][k] + dp[i - 1][j - 1][k - v[i]];

由上面的转移方程可以看出来,可以去掉一维,就是dp[j][k] = dp[j - 1][k - v[i]] + dp[j][k];

/*****************************************
Author      :Crazy_AC(JamesQi)
Time        :2015
File Name   :
*****************************************/
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <sstream>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <limits.h>
using namespace std;
#define MEM(a,b) memset(a,b,sizeof a)
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> ii;
const int inf = 1 << 30;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
inline int Readint(){
	char c = getchar();
	while(!isdigit(c)) c = getchar();
	int x = 0;
	while(isdigit(c)){
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x;
}
int n,m,t;
int a[35], dp[35][510];
int main()
{	
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		memset(dp, 0,sizeof dp);
		for (int i = 1;i <= n;i++)
			scanf("%d",&a[i]);
		dp[0][0] = 1;
		for (int i = 1;i <= n;i++){
			for (int j = n;j >= 1;--j){
				for (int k = m;k >= a[i];--k)
					dp[j][k] += dp[j - 1][k - a[i]];
			}
		}
		int ans;
		bool flag=false;
		for (int j = n;j >= 1;--j){
			ans = 0;
			for (int k = m;k >= 0;k--)
				ans += dp[j][k];
			if (ans){
				printf("You have %d selection(s) to buy with %d kind(s) of souvenirs.\n", ans, j);
				flag = true;
				break;
			}
		}
		if (!flag) printf("Sorry, you can't buy anything.\n");
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三维背包问题是指在三个维度上有不同的物品和容量限制,求解如何将物品放入背包使得总价值最大,同时满足每个维度的容量限制。 在Matlab中,可以使用动态规划算法来解决三维背包问题。具体步骤如下: 1. 定义三维数组dp(i,j,k),表示在前i个物品中,每个维度的容量限制分别为j和k时的最大价值。 2. 初始化dp数组为0,即dp(i,j,k)=0。 3. 对于每个物品i,遍历每个维度的容量限制j和k,如果当前物品的尺寸不超过当前维度的容量限制,则更新dp数组: dp(i,j,k) = max(dp(i-1,j,k), dp(i-1,j-size_i,k) + value_i, dp(i-1,j,k-size_i) + value_i, dp(i-1,j-size_i,k-size_i) + value_i) 其中,size_i表示物品i在第一个维度上的尺寸,value_i表示物品i的价值。 4. 返回dp(n,c1,c2),其中n为物品总数,c1和c2为每个维度的容量限制。 下面是Matlab代码实现: ```matlab function [maxValue] = knapsack3D(size, value, limit) % size: n*3矩阵,每行表示一个物品在三个维度上的尺寸 % value: n*1矩阵,每行表示一个物品的价值 % limit: 1*3矩阵,每个元素表示对应维度的容量限制 % maxValue: 背包能够装下的最大价值 n = size(size, 1); dp = zeros(n+1, limit(1)+1, limit(2)+1, limit(3)+1); for i = 1:n for j = 1:limit(1)+1 for k = 1:limit(2)+1 for l = 1:limit(3)+1 if j>=size(i,1) && k>=size(i,2) && l>=size(i,3) dp(i+1,j,k,l) = max(dp(i,j,k,l), dp(i,j-size(i,1),k,l)+value(i), dp(i,j,k-size(i,2),l)+value(i), dp(i,j,k,l-size(i,3))+value(i), dp(i,j-size(i,1),k-size(i,2),l)+value(i), dp(i,j-size(i,1),k,l-size(i,3))+value(i), dp(i,j,k-size(i,2),l-size(i,3))+value(i), dp(i,j-size(i,1),k-size(i,2),l-size(i,3))+value(i)); else dp(i+1,j,k,l) = dp(i,j,k,l); end end end end end maxValue = dp(n+1,limit(1)+1,limit(2)+1,limit(3)+1); end ``` 其中,n为物品总数,size为n*3矩阵,每行表示一个物品在三个维度上的尺寸,value为n*1矩阵,每行表示一个物品的价值,limit为1*3矩阵,每个元素表示对应维度的容量限制。函数返回背包能够装下的最大价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值