动态规划特训:免费糖果(UVA10118)神奇的记忆话搜索

这篇博客介绍了如何使用动态规划解决UVA10118问题,即从四堆糖中拿糖放入篮子,若有相同颜色糖果则放入口袋,目标是最大化糖果数量。解题策略涉及多阶段DP,利用top数组模拟堆顶位置,通过mark数组记录口袋颜色,实现类似于回溯法的状态转移。
摘要由CSDN通过智能技术生成

解题思路:多阶段dp,每次可以选择从四堆糖顶部拿出一颗。用dp[][][][]记录所有状态,那么如何处理状态的转换呢。这里用了非常巧妙的方法。定义一个一维数组top[5]记录四堆糖顶部的位置,动态规划时取了该位置的糖则top[i]++,递归返回则top[i]--。处理方式非常类似回溯法。用mark数组记录口袋里的颜色,处理用top数组,类似回溯法,具体实现方式可参见代码。

题目大意:有四堆糖,每次从堆顶拿出一个放篮子里,篮子里如果有相同颜色的糖果则把他们拿出放在自己口袋里。如果篮子满了且里面没有相同颜色的糖果,游戏结束,口袋里的糖果归他,问最多可以拿多少糖。

Sample Input
5
1 2 3 4
1 5 6 7
2 3 3 3
4 9 8 6
8 7 2 1
1
1 2 3 4
3
1 2 3 4
5 6 7 8
1 2 3 4
0
Sample Output
8
0
3

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int n, a[50][5], dp[50][50][50][50],top[5];
bool mark[100];

int f(int x) //这里递归函数的参数比较特殊,使用口袋里的糖果个数
{
	int &ans = dp[top[1]][top[2]][top[3]][top[4]];
	if (ans != -1) return ans;
	if (x == 5) return ans;  //返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值