uva 10118 记忆化搜索

Little Bob is playing a game. He wants to win some candies in it - as many as possible.

There are 4 piles, each pile contains N candies. Bob is given a basket which can hold at most 5

candies. Each time, he puts a candy at the top of one pile into the basket, and if there’re two candies

of the same color in it, he can take both of them outside the basket and put them into his own pocket.

When the basket is full and there are no two candies of the same color, the game ends. If the game is

played perfectly, the game will end with no candies left in the piles.

For example, Bob may play this game like this (N = 5):

Step1 Initial Piles Step2 Take one from pile #2

Piles Basket Pocket Piles Basket Pocket

1 2 3 4 1 3 4

1 5 6 7 1 5 6 7

2 3 3 3 nothing nothing 2 3 3 3 2 nothing

4 9 8 6 4 9 8 6

8 7 2 1 8 7 2 1

Step3 Take one from pile #2 Step4 Take one from pile #3

Piles Basket Pocket Piles Basket Pocket

1 3 4 1 4

1 6 7 1 6 7

2 3 3 3 2 5 nothing 2 3 3 3 2 3 5 nothing

4 9 8 6 4 9 8 6

8 7 2 1 8 7 2 1

Step5 Take one from pile #2 Step6 Put two candies into his pocket

Piles Basket Pocket Piles Basket Pocket

1 4 1 4

1 6 7 1 6 7

2 3 3 2 3 3 5 nothing 2 3 3 2 5 a pair of 3

4 9 8 6 4 9 8 6

8 7 2 1 8 7 2 1

Note that different numbers indicate different colors, there are 20 kinds of colors numbered 1..20.

‘Seems so hard...’ Bob got very much puzzled. How many pairs of candies could he take home at

most?

Input

The input will contain not more than 10 test cases. Each test case begins with a line containing a single

integer n(1 ≤ n ≤ 40) representing the height of the piles. In the following n lines, each line contains

four integers xi1

, xi2

, xi3

, xi4

(in the range 1..20). Each integer indicates the color of the corresponding

candy. The test case containing n = 0 will terminate the input, you should not give an answer to this

case.

Output

Output the number of pairs of candies that the cleverest little child can take home. Print your answer

in a single line for each test case.

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<cmath>
#include<stdlib.h>
#include<map>
#include<set>
#include<time.h>
#include<vector>
#include<queue>
#include<string>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1e-8
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
typedef pair<int , int> pii;
#define maxn 42

int d[maxn][maxn][maxn][maxn];
int a[maxn][4];
int top[4];
int n;

void init()
{
    memset(d, -1, sizeof d);
    for(int i = 0; i < 4; i++)
    top[i] = 0;
}

int dfs(int cnt, bool *hash)
{
    int &res = d[top[0]][top[1]][top[2]][top[3]];
    if(res != -1) return res;
    if(cnt == 5) return res = 0;
    int ans = 0;
    for(int i = 0; i < 4; i++)
    {
        if(top[i] >= n) continue;
        top[i]++;
        int color = a[top[i]][i];
        if(hash[color])
        {
            hash[color] = false;
            int t = dfs(cnt - 1, hash);
            ans = max(ans, t + 1);
            hash[color] = true;
        }
        else
        {
            hash[color] = true;
            int t = dfs(cnt + 1, hash);
            ans = max(ans, t);
            hash[color] = false;
        }
        top[i]--;
    }
    return res = ans;
}

int main()
{
    while(~scanf("%d", &n) && n)
    {
        init();
        for(int i = 1; i <= n; i++)
        for(int j = 0; j < 4; j++)
        scanf("%d", &a[i][j]);

        bool hash[22];
        memset(hash, false, sizeof hash);
        printf("%d\n", dfs(0, hash));
    }
    return 0;
}

/*

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

*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 15:48:55

uva 10118 记忆化搜索的相关文章

UVa 10118 记忆化搜索 Free Candies

假设在当前状态我们第i堆糖果分别取了cnt[i]个,那么篮子里以及口袋里糖果的个数都是可以确定下来的. 所以就可以使用记忆化搜索. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 45; 7 const int maxm = 4; 8 9 int n; 10 11 int candy[maxn][maxm

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

题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果, 那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走多少对糖果. 析:首先看到的是时间30s,这么长时间,一想应该是暴力了吧,后来一想应该是记忆化搜索,既然这么长时间,应该得优化一下,不然可能超时, 但是数据好像挺水,才运行了60ms,并不知道是怎么回事,接下来说说这个题,用 d[a,b,c,d] 来表示 分别从 第一,二,三,四堆拿的最多糖果, 如

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <

UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)

题目链接:uva 1252 题意: 有n个长度为m的二进制串,每个都是不同的. 为了把所有字符串区分开,你可以询问,每次可以问某位上是0还是1. 问最少提问次数,可以把所有字符串区分开来. 思路来源于:点击打开链接 思路: m很小,可以考虑状态压缩. dp[s1][s2]表示询问的状态为s1时,此时能猜到状态包含s2时最小需要的步数. 当询问的几位=s2的二进制串小于2时就能区分出来了,dp[s1][s2]=0: 不能区分则再询问一次,s1|=(1<<k),如果问某位为0,则s2不变,问某位为

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

题目链接:uva 10581 - Partitioning for fun and profit 题目大意:给定m,n,k,将m分解成n份,然后按照每份的个数排定字典序,并且划分时要求ai?1≤ai,然后输出字典序排在k位的划分方法. 解题思路:因为有ai?1≤ai的条件,所以先记忆化搜索处理出组合情况dp[i][j][s]表示第i位为j,并且剩余的未划分数为s的总数为dp[i][j][s],然后就是枚举每一位上的值,判断序列的位置即可. #include <cstdio> #include

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

题目:UVA - 10118Free Candies(记忆化搜索) 题目大意:给你四堆糖果,每个糖果都有颜色.每次你都只能拿任意一堆最上面的糖果,放到自己的篮子里.如果有两个糖果颜色相同的话,就可以将这对糖果放进自己的口袋.自己的篮子最多只能装5个糖果,如果满了,游戏就结束了.问你能够得到的最多的糖果对数. 解题思路:这题想了好久,好不容易把状态想对了,结果脑子发热,又偏离了方向.dp[a][b][c][d]:四堆糖果现在在最上面的是哪一个.因为下面的糖果如果确定了,那么接下了不管你怎么取,最优

UVA - 10817 Headmaster&#39;s Headache (状压dp+记忆化搜索)

题意:有M个已聘教师,N个候选老师,S个科目,已知每个老师的雇佣费和可教科目,已聘老师必须雇佣,要求每个科目至少两个老师教的情况下,最少的雇佣费用. 分析: 1.为让雇佣费尽可能少,雇佣的老师应教他所能教的所有科目. 2.已聘老师必须选,候选老师可选可不选. 3.dfs(cur, subject1, subject2)---求出在当前已选cur个老师,有一个老师教的科目状态为 subject1,有两个及以上老师教的科目状态为 subject2的情况下,最少的雇佣费用. dp[cur][subje

UVa 10817 (状压DP + 记忆化搜索) Headmaster&#39;s Headache

题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两个老师教而且使得总工资最少. 分析: 因为s很小,所以可以用状态压缩. dp(i, s1, s2)表示考虑了前i个人,有一个人教的课程的集合为s1,至少有两个人教的集合为s2. 在递归的过程中,还有个参数s0,表示还没有人教的科目的集合. 其中m0, m1, s0, s1, s2的计算用到位运算,还

UVA - 10913Walking on a Grid(记忆化搜索)

题目:Walking on a Grid 题目大意:给出N * N的矩阵,每个格子里都有一个值,现在要求从(1,1)走到(n, n),只能往下,左,右这三个方向走,并且要求最多只能取k个负数,求这样的要求下能得到的走过格子的值之和最大. 解题思路:记忆化搜索,但是这里要四维的,因为要记录方向,为了防止走回头的路,并且取了几个负数也要记录.然后就是dfs了.状态转移方程:dp[x][y][d][k] = dp[x + dir[i][0]][y + dir[i][1]][i][k1] + G[x][