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

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

解题思路:这题想了好久,好不容易把状态想对了,结果脑子发热,又偏离了方向。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 - Free Candies(记忆化搜索)

    题目大意:10118 - Free Candies 题目大意:有4堆糖果, 每堆糖果有n颗糖果,然后给出每颗糖果的类型1~20,然后只有取走当前堆的前面一颗糖果后才可以取后面的糖果, 然后小伙伴有一个 ...

  2. uva 707(记忆化搜索)

    题意:在一个方阵中,一个强盗犯要逃跑.你是警察要去抓他,现在你手上有若干线索他们会告诉你第i时刻一个方阵中他们没有看见强盗.在t秒后全部道路会封锁.让你通过线索来判断是不是能够找到小偷在某一秒的位置. ...

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

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

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

    题目链接:UVA - 10118 题目是PDF就不贴了,大意就是有四堆糖果,每堆有n个,有个人有个能盛五个糖的篮子,每次可以任选一堆糖,取最上面的那个放到篮子里,如果篮子里有两个颜色相同的,就可以把这 ...

  5. UVa 10118 记忆化搜索 Free Candies

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

  6. UVA - 10118 Free Candies(记忆化搜索/状压)

    传送门 方法一 一开始我确实是这样想的,设d[i][j][k][p][S]d[i][j][k][p][S]d[i][j][k][p][S]为四堆分别拿了i,j,k,pi,j,k,pi,j,k,p个,当 ...

  7. 【UVA 437】The Tower of Babylon(记忆化搜索写法)

    [题目链接]:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  8. UVa 1629 切蛋糕(记忆化搜索)

    https://vjudge.net/problem/UVA-1629 题意: 有一个n行m列的网格蛋糕上有一些樱桃.每次可以用一刀沿着网格线把蛋糕切成两块,并且只能直切不能拐弯.要求最后每一块蛋糕上 ...

  9. UVA - 10253 Series-Parallel Networks(递推式、记忆化搜索写法)

    题目:UVA-10253 题目翻译(来自蓝书): 串并联网络有两个端点,一个叫源,一个叫汇,递归定义如下: (1) 一条单独的边是串并联网络. (2) 若G1和G2是串并联网络,把它们的源和源接在一起 ...

最新文章

  1. Python 到底该怎么学才好?你关心的答案来了
  2. 字节跳动新员工入职一周,工作很少,每天很闲,从不加班!公司一堆漂亮小姐姐!完全不像外面说得那么忙!...
  3. python去除中间空格只留一个_汇总初学Python的21个操作难点,看完别再去踩坑了...
  4. 查看删除的帐号的DN名称(活动目录快照配置管理系列六)
  5. 查看oracle系统信息,查看 ORACLE 系统级信息
  6. springboot在intellij中的热部署(Hot swapping)配置
  7. C/C++基础语法复习(二):C++ 面向对象编程,你需要知道的点
  8. java g1的并行_Java 11好用吗
  9. Linux环境安装配置Swftools
  10. Spring-3.2.4 + Quartz-2.2.0集成实例
  11. 使用PosixFilePermission的Java设置文件权限
  12. dual mysql 获取序列_如何获取 MySQL 插入数据的自增 ID
  13. 基于arduino uno + WS2812b RGB灯带单一颜色跑马灯控制程序
  14. QAV250四轴穿越机安装全程详解(多图)
  15. 04_iTween_第三天--相机路径跟随(PutOnPath)
  16. 逆向分析QQ消息自动回复机器人设计
  17. 错误的SQL脚本,错误消息 4104
  18. ROS 应用开发入门 发布者Publisher的编程
  19. STM32MP157驱动开发——Linux IIO驱动(上)
  20. 风林评《如何写影评》|如何写影评

热门文章

  1. python 行列分不清
  2. 【总结向】从CMRC2019头部排名看中文MRC
  3. 【小社交】谁是下一个陌陌?陌生人社交网络大起底!
  4. [乐意黎原创]OFO小黄车提示你有未完成订单/未知错误的解决方法
  5. linux spool目录 删除,Linux知识:/var/spool/clientmqueue 下垃圾文件删除
  6. 易优CMS网站建设类企业网站模板 互联网营销网站模板
  7. ESP32开发之旅——ssd1306 OLED屏的使用
  8. c语言大数运算知乎,为什么知乎上大多数人不推荐C语言入门?
  9. (PC+WAP)织梦模板财经新闻资讯类网站
  10. 2022年高教社杯国赛E题思路——小批量物料的生产安排