题目: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. 例3.1 猜猜数据结构 UVa11995

    1.标题叙述性说明:点击打开链接 2.解题思路:据来推測一种可能的数据结构,备选答案有"栈,队列.优先队列".结果也可能都不是或者不确定. STL中已经有这三种数据结构了,因此直接 ...

  2. Queue 消息的发送与接收(PTP 消息传递模型)

    上篇博客写到了JMS两种消息模型(P2P.pub/sub)<JMS两种消息模型>.本篇博客通过一个实例来进一步了解P2P模型. Queue消息的发送与接收--PTP消息传递模型,样例: Q ...

  3. ThinkPHP连接数据库出现的错误:Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'

    最近看了看ThinkPHP.在连接mysql数据库时出现了错误:Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'.意思就是没有PDO(PHP数据对象 ...

  4. [Android学习笔记]LinearLayout布局,剩余空间的使用

    转自:http://segmentfault.com/q/1010000000095725 如果使得一个View占用其父View的剩余空间? 答案是使用:android:layout_weight = ...

  5. [Android学习笔记]Bitmap,BitmapDrawable,BitmapFactory学习笔记

    Bitmap:图片文件的封装,可以看做是一张位图此类中的静态方法可以通过源Bitmap创建新的Bitmap对象此类封装了位图的一些信息Bitmap文档 BitmapFactory:一个工具类,用于创建 ...

  6. [Android学习笔记]捕获物理回退事件

    物理回退按钮默认情况下是finish当前activity,返回上一个activity 当需要获取物理回退按钮的相应事件时候,可以这么做 步骤如下: 1.override当前activity的onKey ...

  7. Oracle 调用存储过程执行CRUD的小DEMO

    -----------------------------修改(表名,主键ID,要修改的列) create or replace procedure pro_code_edit(p_tbname in ...

  8. VSTO学习笔记(一)VSTO概述

    原文:VSTO学习笔记(一)VSTO概述 接触VSTO纯属偶然,前段时间因为忙于一个项目,在客户端Excel中制作一个插件,从远程服务器端(SharePoint Excel Services)上下载E ...

  9. php 双向队列类

    (deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构.双向队列中的元素能够从两端弹出,其限定插入和删除操作在表的两端进行. 在实际使用中,还能够有输出受限的双向队 ...

  10. UVA 11100 The Trip, 2007 贪心(输出比较奇葩)

    题意:给出n个包的大小,规定一个大包能装一个小包,问最少能装成几个包. 只要排序,然后取连续出现次数最多的数的那个次数.输出注意需要等距输出. 代码: /* * Author: illuz <i ...