uva 10118 free candies

本文介绍了一个基于记忆化搜索的算法,解决如何从四堆不同类型的糖果中取出最多数量的成对糖果的问题。通过使用四维数组记录每种状态下的最优解,避免重复计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:有4堆糖果, 每堆糖果有n颗糖果,然后给出每颗糖果的类型1~20,然后只有取走当前堆的前面一颗糖果后才可以取后面的糖果, 然后小伙伴有一个篮子,篮子可以装5个糖果,如果篮子中的糖果存在相同类型的两个糖果,便可以将这两颗糖果算成一对放进腰包,问,小伙伴按什么样的方式取糖果可以取到最多的糖果。

解题思路:记忆化搜索,开一个四维数组记录当前4堆糖果取走相应个数后能拿到的最多对糖果数。

//  Created by Chenhongwei in 2015.
//  Copyright (c) 2015 Chenhongwei. All rights reserved.

#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"
#include"climits"
#include"queue"
#include"cmath"
#include"map"
#include"set"
#include"stack"
#include"vector"
#include"sstream"
#include"algorithm"
using namespace std;
typedef long long ll;
int g[50][5], dp[50][50][50][50], vis[25], b[10];
int n;
int dfs(int cnt)
{
	int &cur = dp[b[0]][b[1]][b[2]][b[3]];
	if (cnt == 5)
		return cur = 0;
	if (cur != -1)
		return cur;
	cur = 0;
	for (int i = 0; i < 4; i++)
	{
		if (b[i] == n)
			continue;
		int tmp = g[b[i]++][i];
		if (vis[tmp])
		{
			vis[tmp] = 0;
			cur = max(cur, dfs(cnt - 1) + 1);
			vis[tmp] = 1;
		}
		else
		{
			vis[tmp] = 1;
			cur = max(cur, dfs(cnt + 1));
			vis[tmp] = 0;
			b[i]--;
		}
		return cur;
	}
	int main()
	{
		//ios::sync_with_stdio(false);
		// freopen("in.txt","r",stdin);
		//freopen("out.txt","w",stdout);
		while (cin >> n && n)
		{
			memset(dp, -1, sizeof dp);
			memset(vis, 0, sizeof vis);
			memset(b, 0, sizeof b);
			for (int i = 0; i < n; i++)
				for (int j = 0; j < 4; j++)
					cin >> g[i][j];
			cout << dfs(0) << endl;
		}
		return 0;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值