题目:UVA - 10118Free Candies(记忆化搜索)

题目大意:给你四堆糖果,每一个糖果都有颜色。每次你都仅仅能拿随意一堆最上面的糖果,放到自己的篮子里。假设有两个糖果颜色同样的话,就行将这对糖果放进自己的口袋。自己的篮子最多仅仅能装5个糖果,假设满了,游戏就结束了。问你可以得到的最多的糖果对数。

解题思路:这题想了好久,好不easy把状态想对了,结果脑子发热,又偏离了方向。dp【a】【b】【c】【d】:四堆糖果如今在最上面的是哪一个。由于以下的糖果假设确定了,那么接下了无论你怎么取,最优的肯定是仅仅有一种。所以能够把如今剩余的糖果的最多数量加上你之前取的那些糖果你能得到的糖果最多数量,就是要求的最多的糖果对数。

dp【a】【b】【c】【d】 = Max(dp【a + 1】【b】【c】【d】 + 0|1, dp[a][b +1】【c】【d】 + 0|1, dp【a】【b】【c + 1】【d】 + 0|1 , dp【a】【b】【c】【d  +1] + 0|1).0 | 1取决于你如今篮子里是否有和我取的那个糖果颜色同样的。相应的篮子里的糖果数量要变化。假设数量等于5了,就说明不能放了,返回0.而且每堆糖果都有最大的数量,取完也是要结束的。这些边界条件要注意.这里发现了一个新的知识:用memcpy的时候假设不是里面的全部数据都要的话,要指明长度,不然可能会出现错误。

代码:

#include <cstdio>
#include <cstring> const int N = 42;
const int M = 5;
const int maxn = 1000005; int candy[N][M];
int top[M];//存放每堆糖果最上面的序号
int f[N][N][N][N];
int n; int Max (const int a, const int b) { return a > b ? a: b; } void init () { memset (f, -1, sizeof (f));
f[n][n][n][n] = 0;//结束状态不论篮子满不满
} bool handle (int r, int c, int k, int *b) {//处理是否有同样的塘果 int *b是篮子,k + 1是里面有的糖果的个数。 int i;
for (i = 0; i < k; i++) { if (candy[r][c] == b[i])
break;
} if (!k || i == k) {
b[k] = candy[r][c];
return false;
} else { for (int j = i; j < k - 1; j++)
b[j] = b[j + 1];
return true;
}
} int dfs (int k, int *bket, int a, int b, int c, int d) { int bket1[M * 2];
int& ans = f[a][b][c][d];
if (k >= M)//篮子满了
return 0;//注意这里ans不一定等于0,由于取糖果的顺序不同的话,这个篮子的情况可能不同
if (ans != -1)
return ans;
top[1] = a;
top[2] = b;
top[3] = c;
top[4] = d;
for (int i = 1; i < M; i++) { /*for (int j = 0; j < k; j++)
bket1[j] = bket[j];*/
memcpy (bket1, bket, k * sizeof (int));//注意
/*for (int j = 0; j < k; j++)
printf ("%d ", bket1[j]);
printf ("\n");*/
if (handle (top[i], i, k, bket1)) { top[i]++;
if (top[i] <= n)
ans = Max (ans, dfs (k - 1, bket1, top[1], top[2], top[3], top[4]) + 1);
} else { top[i]++;
if (top[i] <= n)
ans = Max (ans, dfs (k + 1, bket1, top[1], top[2], top[3], top[4]));
}
top[i]--;
}
return ans;
} int main () { while (scanf ("%d", &n), n) { for (int i = 0; i < n; i++)
for (int j = 1; j < M; j++)
scanf ("%d", &candy[i][j]); int b[M * 2];
init ();
printf ("%d\n", dfs (0, b, 0, 0, 0, 0));
// printf ("%d\n", f[n][n - 1][0][0]);
/* for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
for (int l = 0; l < n; l++)
printf ("%d ", f[i][j][k][l]);
printf ("\n");
}
printf ("\n");
}
printf ("\n");
}
printf ("\n");*/
}
return 0;
}

UVA - 10118Free Candies(记忆化搜索)的更多相关文章

  1. uva 10118,记忆化搜索

    这个题debug了长达3个小时,acm我不能放弃,我又回来了的第一题! 一开始思路正确,写法不行,结果越改越乱 看了网上某神的代码,学习了一下 coding+debug:4小时左右,记忆化搜索+dp类 ...

  2. UVA - 1631 Locker 记忆化搜索

    题意:给定两个密码串,每次可以让1~3个相邻的密码向上或者向下滚动,每个密码是 ,问最少需要多少次滚动可以让原串成为目标串? 思路:假设当前要让第i位密码还原,我们可以同时转动,不同的转动方式会影响后 ...

  3. UVA 11468 Substring (记忆化搜索 + AC自动鸡)

    传送门 题意: 给你K个模式串, 然后,再给你 n 个字符, 和它们出现的概率 p[ i ], 模式串肯定由给定的字符组成. 且所有字符,要么是数字,要么是大小写字母. 问你生成一个长度为L的串,不包 ...

  4. UVA - 10118 Free Candies 记忆化搜索经典

    思路:d[a][b][c][d]表示从已经第一个篮子取了a颗糖,第二个取了b颗糖,第三个取了c颗糖,第四个取了d颗糖最多还能够获得多少糖果.首先明白一个问题:如果能分别取a,b,c,d个,不论如何取, ...

  5. UVa 10118 Free Candies (记忆化搜索+哈希)

    题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果, 那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走 ...

  6. UVa 10118 记忆化搜索 Free Candies

    假设在当前状态我们第i堆糖果分别取了cnt[i]个,那么篮子里以及口袋里糖果的个数都是可以确定下来的. 所以就可以使用记忆化搜索. #include <cstdio> #include & ...

  7. uva 10581 - Partitioning for fun and profit(记忆化搜索+数论)

    题目链接:uva 10581 - Partitioning for fun and profit 题目大意:给定m,n,k,将m分解成n份,然后依照每份的个数排定字典序,而且划分时要求ai−1≤ai, ...

  8. UVA - 10917 - Walk Through the Forest(最短路+记忆化搜索)

    Problem    UVA - 10917 - Walk Through the Forest Time Limit: 3000 mSec Problem Description Jimmy exp ...

  9. UVa 10285 Longest Run on a Snowboard - 记忆化搜索

    记忆化搜索,完事... Code /** * UVa * Problem#10285 * Accepted * Time:0ms */ #include<iostream> #includ ...

随机推荐

  1. ORACLE 中的一些特殊符号

    oracle通配符,运算符的使用 用于where比较条件的有: 等于:=.<.<=.>.>=.<> 包含:in.not in exists.not exists 范 ...

  2. Lambda高手之路第一部分

    转http://www.cnblogs.com/lazycoding/archive/2013/01/06/2847574.html 介绍 Lambda表达式是使代码更加动态,易于扩展并且更加快速(看 ...

  3. Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一)

    原文:Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一) 拓展压缩包的使用方式详细介绍 1:将拓展包解压:ThinkPHP3.1.2_Extend.zip   --> 将其下的 \ ...

  4. 基于三星I9250演示自己弄的Miracast功能-手机对手机

    最终把Miracast功能測试通了,为了节省时间.我的Source端和Sink端都採用同一个机型.这样能够降低我为目标机编译4.4.2源码所耗费的时间.今天简单录制了一段视频.视频是用手机录制的,室内 ...

  5. leetcode回文子串拆分-最小拆分次数

    转载请注明来自souldak,微博:@evagle 上一篇是要输出所有的可能拆分,这回是要输出拆分次数最少的切割次数. 如果直接按照上一篇那么做的话,就会超时,因为我们在判断s[i][j]是否是回文的 ...

  6. Python基础 - 内建函数

    什么是内建函数 在Python的手册中,名叫build-in Functions,中文可以称为内建函数. 内建函数就像dos系统的内部命令,他不依赖于外部模块,也就是说: 内建函数就是:安装好Pyth ...

  7. Jeecg社区wiki在开放,最终能够在线看文档啦!!!

    Jeecg社区wiki在开放,最终能够在线看文档啦! .! 2014-12-18 scott JEECG jeecg开源社区wiki正式启动了.方便大家看文档 訪问地址是: http://osbaba ...

  8. aix 下 实现goldengate 随os启动而自己主动启动的脚本

    aix 下 实现goldengate 随os启动而自己主动启动的脚本: 1.用oracle用户建立/u01/info.txt,文件内容例如以下: sh date start mgr 2.chmod + ...

  9. ActivityGroup简单介绍

    ActivityGroup简单介绍 1.ActivityGroup的核心就是继承了该类,可以通过getLocalActivityManager()得到一个LocalActivityManager 如, ...

  10. Linux+Apache+Mysql+Php

    CentOS 6.3下源码安装LAMP(Linux+Apache+Mysql+Php)环境 一.简介 什么是LAMP    LAMP是一种Web网络应用和开发环境,是Linux, Apache, My ...