UVA 10118 Free Candies
https://vjudge.net/problem/UVA-10118
题目
桌上有4堆糖果,每堆有$N$($N\leqslant 40$)颗。有个熊孩子拿了个可以装5颗糖的篮子,开始玩无聊的装糖游戏。他每次选一堆糖,并把这堆最上面的糖装进篮子里面,如果篮子里有两个种类相同的糖,那么他就把这两个糖装进自己的口袋里。给出四堆糖中每一颗糖的种类(1..20),问最多能装多少对糖。
题解
一开始看这题,拿糖的顺序有$\mathcal{O}(P(4^40,40))$种,一下就茫然了(估计得太松了……)
设dp[a][b][c][d]为分别拿了这么多桌上的糖的数量时最多还能拿多少糖,很容易写出转移方程……
这样状态数为$\mathcal{O}(n^4)$,转移数为4,复杂度$\mathcal{O}(n^4)$,还是可以
有个问题是篮子的空间有限制,但四堆糖确定后篮子剩余空间就确定了
计算到这里的时候说明能到达这个状态
因为一旦篮子里有两个相同的糖就会装进口袋,所以篮子里不会有两个相同的糖
那么要到达这个状态,篮子里一定只剩拿了奇数的糖
(又是乱证明= =)
只有20种糖,直接二进制压位
AC代码
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define PER(r,x,y) for(register int r=(x); r>(y); r--)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif
int d[47][47][47][47];
int p[47][4];
int n;
int DP(int arr[4], int k, int cp) {
int &now=d[arr[0]][arr[1]][arr[2]][arr[3]];
if(now>=0) return now;
now=0;
REP(i,0,4) {
if(arr[i]<n) {
int iid=p[arr[i]][i];
arr[i]++;
if(k&(1<<iid)) {
now = max(now,DP(arr,k^(1<<iid),cp-1)+1);
} else {
if(cp+1<=4) {
now = max(now,DP(arr,k^(1<<iid),cp+1));
}
}
arr[i]--;
}
}
return now;
}
int main() {
#ifdef sahdsg
freopen("in.txt", "r", stdin);
#endif
while(~scanf("%d", &n) && n) {
memset(d,-1,sizeof d);
REP(i,0,n) {
scanf("%d%d%d%d", &p[i][0], &p[i][1], &p[i][2], &p[i][3]);
}
int h[4]; memset(h,0,sizeof h);
DP(h,0,0);
printf("%d\n", d[0][0][0][0]);
}
return 0;
}
UVA 10118 Free Candies的更多相关文章
- UVA - 10118 Free Candies 记忆化搜索经典
思路:d[a][b][c][d]表示从已经第一个篮子取了a颗糖,第二个取了b颗糖,第三个取了c颗糖,第四个取了d颗糖最多还能够获得多少糖果.首先明白一个问题:如果能分别取a,b,c,d个,不论如何取, ...
- UVa 10118 Free Candies (记忆化搜索+哈希)
题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果, 那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走 ...
- UVA - 10118 Free Candies(免费糖果)(dp---记忆化搜索)
题意:桌上有4堆糖果,每堆有N(N<=40)颗.佳佳有一个最多可以装5颗糖的小篮子.他每次选择一堆糖果,把最顶上的一颗拿到篮子里.如果篮子里有两颗颜色相同的糖果,佳佳就把它们从篮子里拿出来放到自 ...
- uva 10118
10118 - Free Candies Time limit: 30.000 seconds Little Bob is playing a game. He wants to win some c ...
- uva 10118(DP)
UVA 10118 题意: 有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果, 如果篮子里有两个相同的糖果,那么就可以把这两个(一对)糖果放进自己 ...
- D - Free Candies UVA - 10118
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVa 10118 记忆化搜索 Free Candies
假设在当前状态我们第i堆糖果分别取了cnt[i]个,那么篮子里以及口袋里糖果的个数都是可以确定下来的. 所以就可以使用记忆化搜索. #include <cstdio> #include & ...
- 【Uva 10118】Free Candies
[Link]: [Description] 有4堆书; 每本书编号从1..20 每堆书都是N本; 然后每次只能从任意一堆的堆顶拿一本书装到自己的口袋里; 你的口袋最多容纳5本书; 当你的口袋里有两本一 ...
- Uva 10118 免费糖果
题目链接:https://uva.onlinejudge.org/external/101/10118.pdf 参考:http://www.cnblogs.com/kedebug/archive/20 ...
随机推荐
- java SPI机制
1. SPI是Service Provider Interfaces的简称.根据Java的SPI规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即Service Provider(服务 ...
- js 常用
js设置 div高度和宽度 function autoHeight() { var h = $(window).height(); var w = $(window).width(); $(" ...
- 安装完成Dynamics 365 CE后别忘了更改维护作业的运行时间
摘要: 微软动态CRM专家罗勇 ,回复309或者20190308可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 安装完毕Dy ...
- 浅谈Semaphore类
Semaphore类有两个重要方法 1.semaphore.acquire(); 请求一个信号量,这时候信号量个数-1,当减少到0的时候,下一次acquire不会再执行,只有当执行一个release( ...
- Vue组件的is具体用法
1.为什么要使用is 在vue的官网组件部分中,有明确的描述:当使用 DOM 作为模板时 (例如,使用 el 选项来把 Vue 实例挂载到一个已有内容的元素上),你会受到 HTML 本身的一些限制,因 ...
- 使用VBScript 脚本 开机播放声音
前言:环境Window 10 第一步写一个 VBScript 脚本 新建一个文本文档,将下面的代码复制到文本文档中,Ctrl+S保存 将文本文档的.txt 后缀 改为.vbs即可 最后,双击这个 vb ...
- sql server 临时表(上) Tempdb概述
一.概述 在sql server里临时表存储在TempDB库中,TempDB是一个系统数据库,它只有Simple恢复模式,也是最小日志记录操作.主要用于存放局部临时表,全局临时表,表变量,都是基于临时 ...
- c/c++ 多线程 std::call_once的应用
多线程 std::call_once的应用 std::call_once的应用:类成员的延迟初始化,并只初始化一次.和static的作用很像,都要求是线程安全的,c++11之前在多线程的环境下,sta ...
- mysql 从一个表中查询,插入到另一个表中
insert into table1(field1) select field1 from table2; ;
- 重装助手教你如何禁用Windows 10快速启动
快速启动是首先在Windows 8中实现并延续到Windows 10的功能,可在启动PC时提供更快的启动时间.它是一个方便的功能,也是大多数人在不知情的情况下使用的功能,但还有一些功能会在他们掌握新P ...