UVA - 10118 Free Candies

题目链接:https://vjudge.net/problem/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.

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.

题解:

  这个题目考虑暴力dp,设dp[i][j][k][h],表示第一列选到i,第二列选到j,第三列选到k,第四列选到h向下走还可以选的最大收益,当然转移就是枚举下一位,向哪里走,选哪个方块就可以了。

  当然肯定有人想为啥不用记篮子中有的球的颜色,因为只要i,j,k,h确定了,那么只要状态合法,那么篮子中的物品就是确定的,也就是说篮子的东西其实是无后效性的。

代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#define MAXN 45
using namespace std;
int dp[MAXN][MAXN][MAXN][MAXN];
bool b[MAXN][MAXN][MAXN][MAXN];
int num[5][MAXN],n;

int dfs(int i,int j,int k,int h,int lan,int cnt){
    if(b[i][j][k][h]) return dp[i][j][k][h];
    if(i>n||j>n||k>n||h>n) return 0;
    if(cnt>=5) return -(1<<30);
    b[i][j][k][h]=1;
    int maxx=0;
    if(lan&(1<<num[i+1][1])) maxx=max(maxx,dfs(i+1,j,k,h,lan^(1<<num[i+1][1]),cnt-1)+1);
    else maxx=max(maxx,dfs(i+1,j,k,h,lan|(1<<num[i+1][1]),cnt+1));
    if(lan&(1<<num[j+1][2])) maxx=max(maxx,dfs(i,j+1,k,h,lan^(1<<num[j+1][2]),cnt-1)+1);
    else maxx=max(maxx,dfs(i,j+1,k,h,lan|(1<<num[j+1][2]),cnt+1));
    if(lan&(1<<num[k+1][3])) maxx=max(maxx,dfs(i,j,k+1,h,lan^(1<<num[k+1][3]),cnt-1)+1);
    else maxx=max(maxx,dfs(i,j,k+1,h,lan|(1<<num[k+1][3]),cnt+1));
    if(lan&(1<<num[h+1][4])) maxx=max(maxx,dfs(i,j,k,h+1,lan^(1<<num[h+1][4]),cnt-1)+1);
    else maxx=max(maxx,dfs(i,j,k,h+1,lan|(1<<num[h+1][4]),cnt+1));
    dp[i][j][k][h]=maxx;
    return maxx;
}

int main(){
    while(1){
        memset(dp,0,sizeof(dp));
        memset(b,0,sizeof(b));
        memset(num,0,sizeof(num));
        scanf("%d",&n);
        if(n==0) break;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=4;j++)
        scanf("%d",&num[i][j]);
        printf("%d\n",dfs(0,0,0,0,0,0));
    }
}
时间: 2024-10-29 02:55:42

UVA - 10118 Free Candies的相关文章

Uva 10118 Free Candies (DP+记忆化搜索)

The Problem 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

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

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

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 记忆化搜索

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 th

10118 - Free Candies(DP)

自己想出来的,一遍AC,0.132s 说说我的思路吧,首先考虑如何表示状态,不难发现,情况非常多,因为怎么拿都行,所以只好增加维度,开四维数组. 由于结构比较无序,所以选择了记忆化搜索 ,受前面<校长的烦恼>的启发,即使我们还要维护篮子中糖果情况,但是我们只需开四维数组就已经足够表示所有的状态了 ,我们大可以将篮子中的情况以及口篮子中糖果的数量放在函数的参数中来维护就可以了,那么我们不难用d[a][b][c][d]表示各堆糖果取到当前状态时口袋中糖果的最大对数 . 如何维护当前篮子中糖果的颜色

uva 10118,记忆化搜索

这个题debug了长达3个小时,acm我不能放弃,我又回来了的第一题! 一开始思路正确,写法不行,结果越改越乱 看了网上某神的代码,学习了一下 /* * Author: Bingo * Created Time: 2015/3/2 21:23:20 * File Name: uva10118.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

dp题目列表

10271 - Chopsticks 10739 - String to Palindrome 10453 - Make Palindrome 10401 - Injured Queen Problem 825 - Walking on the Safe Side 10617 - Again Palindrome 10201 - Adventures in Moving - Part IV 11258 - String Partition 10564 - Paths through the Ho

小白书关于动态规划

10192 最长公共子序列 http://uva.onlinejudge.org/index.php?option=com_onlinejudge& Itemid=8&page=show_problem&category=114&problem=1133&mosmsg= Submission+received+with+ID+13297616 */ #include <cstdio> #include <string.h> #include&