zoukankan      html  css  js  c++  java
  • UVa 10118 Free Candies (记忆化搜索+哈希)

    题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果,

    那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走多少对糖果。

    析:首先看到的是时间30s,这么长时间,一想应该是暴力了吧,后来一想应该是记忆化搜索,既然这么长时间,应该得优化一下,不然可能超时,

    但是数据好像挺水,才运行了60ms,并不知道是怎么回事,接下来说说这个题,用 d[a,b,c,d] 来表示 分别从 第一,二,三,四堆拿的最多糖果,

    如果篮子满了就返回,如果拿空了某一堆要停止再拿了,再就是如果曾经有过这个状态直接返回值就好,不用再重复计算,节约时间,再就是用Hash,

    来匹配糖果,原来全是false,如果从true变成false,那么就说明有成对,就拿出来,如果从false变成true,说明又得住篮子里放一颗,一定要记住,

    要及时改回来,刚开始忘了,怎么运行都不对。。。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    const int maxn = 40 + 5;
    int d[maxn][maxn][maxn][maxn];
    int n, a[4][maxn], top[4];//top表示第 i 堆糖果拿到第几个了
    bool Hash[maxn];//判断是不是成对
    
    int solve(int cur){
        if(d[top[0]][top[1]][top[2]][top[3]] != -1)  //如果已经存在这种状态,直接返回就好了
            return d[top[0]][top[1]][top[2]][top[3]];
        if(cur == 5)  return 0;//篮子满了
    
        int ans = 0;
        for(int i = 0; i < 4; ++i){
            if(top[i] == n)  continue;//某一堆空了
    
            int x = a[i][top[i]++];
            if(Hash[x]){//从true变成false
                Hash[x] = false;
                ans = max(ans, solve(cur-1)+1);
                Hash[x] = true;//要记得及时改回来
            }
            else{
                Hash[x] = true;
                ans = max(ans, solve(cur+1));
                Hash[x] = false;
            }
            --top[i];
        }
        return d[top[0]][top[1]][top[2]][top[3]] = ans;//返回并赋值给d
    }
    
    int main(){
    //    freopen("in.txt", "r", stdin);
        while(scanf("%d", &n) == 1 && n){
            for(int i = 0; i < n; ++i)//把每一列糖果变成每一行
                for(int j = 0; j < 4; ++j)
                    scanf("%d", &a[j][i]);
    
            memset(d, -1, sizeof(d));//清零
            memset(top, 0, sizeof(top));
            memset(Hash, false, sizeof(Hash));
            printf("%d
    ", solve(0));
        }
        return 0;
    }
    
  • 相关阅读:
    Docker+Nginx 部署Vue+Element前端项目
    MySql取字段逗号分隔的第一个
    Mysql数据库中从表字段中存储了主表以逗号隔开的主键ID,现需求查询从表数据以及以逗号隔开的字段改为主表名称隔开(group_count() find_in_set())
    IIS 错误500.21解决方法
    IIS 出现500.19 错误处理解决方式
    Linux中vim的三种模式
    Centos7 .Net Core 使用Supervisor守护进程,进行后台运行
    Nginx反代理ASP.NET Core项目
    C# vb .net实现圆角矩形特效滤镜
    C# vb .net实现旋转特效滤镜
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5602960.html
Copyright © 2011-2022 走看看