洛谷 P1541 乌龟棋 (四维费用背包)

一开始直接用01背包
后来发现这个物品和位置有关。

也就是价值不是固定的

后来看了题解
看了卡片最多就4

所以这是一个四维费用的背包,
每一维是卡片的数量
价值就是当前的位置的价值。
但是与常规的背包还是有点不同
代码中没有枚举物品这一项
实际上循环里面的四个卡片的判断语句就是枚举四个物品
这里是先体积后物品,保证了这四个物品只选了一件
分组背包中同一组内物品的循环顺序也是先提及后物品

#include<cstdio>
#include<cstring>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;
 
const int MAXN = 45;
const int MAXM = 360;
int f[MAXN][MAXN][MAXN][MAXN];
int num[MAXM], g[10], n, m, x;

void up(int& x, int a) { x = max(x, a); }
 
int main()
{
	scanf("%d%d", &n, &m);
	_for(i, 1, n) scanf("%d", &num[i]);
	_for(i, 1, m) 
	{
		scanf("%d", &x);
		g[x]++;
	}
	
	f[0][0][0][0] = num[1];
	_for(a, 0, g[1])
		_for(b, 0, g[2])
			_for(c, 0, g[3])
				_for(d, 0, g[4])
				{
					int &t = f[a][b][c][d];
					int r = 1 + a + b * 2 + c * 3 + d * 4;
					if(a) up(t, f[a-1][b][c][d] + num[r]);
					if(b) up(t, f[a][b-1][c][d] + num[r]);
					if(c) up(t, f[a][b][c-1][d] + num[r]);
					if(d) up(t, f[a][b][c][d-1] + num[r]);
				}
	
	printf("%d\n", f[g[1]][g[2]][g[3]][g[4]]);
	
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值