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

    题意:

    有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,

    如果篮子里有两个相同的糖果,那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走多少对糖果。糖果种类最多20种. 

    (黑书 148 免费糖果)

    思路:

    1. 这一题有点逆向思维的味道,dp[a, b, c, d] 表示从每堆中分别拿 a, b, c, d 个时,最多能拿多少个糖果;

    2. 注意一点:当拿到 a, b, c, d 时,不能再拿了,此时结果肯定就会固定。利用这一点性质,采用记忆化搜索能有效的减少重复子结构的计算;

    3. 题目是只有 0 0 0 0 这一个出发点的,根据这个出发点进行深搜,最终得出结果。

    4. 本题可谓是深搜 + 记忆化搜索的经典,状态不是那么明显,子结构也不是那么好抽象,因为转移的末状态并不是固定的,是在不断的搜索中求出来的;

    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    const int MAXN = 41;
    int pile[4][MAXN], dp[MAXN][MAXN][MAXN][MAXN];
    int n, top[4];
    
    int dfs(int count, bool hash[]) {
        if (dp[top[0]][top[1]][top[2]][top[3]] != -1)
            return dp[top[0]][top[1]][top[2]][top[3]];
    
        if (count == 5) 
            return dp[top[0]][top[1]][top[2]][top[3]] = 0;
    
        int ans = 0;
        for (int i = 0; i < 4; i++) {
            if (top[i] == n) continue;
            int color = pile[i][top[i]];
            top[i] += 1;
            if (hash[color]) {
                hash[color] = false;
                ans = max(ans, dfs(count-1, hash) + 1);
                hash[color] = true;
            } else {
                hash[color] = true;
                ans = max(ans, dfs(count+1, hash));
                hash[color] = false;
            }
            top[i] -= 1;
        }
        return dp[top[0]][top[1]][top[2]][top[3]] = ans;
    }
    
    int main() {
        while (scanf("%d", &n) && n) {
            for (int i = 0; i < n; i++)
                for (int j = 0; j < 4; j++)
                    scanf("%d", &pile[j][i]);
            bool hash[25];
            memset(dp, -1, sizeof(dp));
            memset(hash, false, sizeof(hash));
            top[0] = top[1] = top[2] = top[3] = 0;
            printf("%d\n", dfs(0, hash));
        }
        return 0;
    }
    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    我的软考之路(五)——数据结构与算法(3)之图
    我的软考之路(四)——数据结构与算法(2)之树与二叉树
    程序员学习资料分享---爱分享的程序员(新浪微博)
    HIT CS科班对计算机专业knowledge的compilation
    我的软考之路(三)——数据结构与算法(1)之线性
    我的软考之路(二)——J2SE宏观总结
    python进阶七_文件操作(三)
    python进阶七_文件操作(二)
    python进阶七_文件操作(一)
    python进阶六_封装与继承
  • 原文地址:https://www.cnblogs.com/kedebug/p/3006493.html
Copyright © 2011-2022 走看看