zoukankan      html  css  js  c++  java
  • HDU 4111 Alice and Bob (博弈+记忆化搜索)

    题意:给定 n 堆石头,然后有两种操作,一种是把从任意一堆拿走一个,另一种是把一个石子放到另一堆上。

    析:整体看,这个题真是不好做,dp[a][b] 表示有 a 堆1个石子,b个操作,操作是指把其他的不是1的堆全部合并起来并全部拿完所以要的操作,

    要注意的是 ,一共有这几种情况。

    1.a 为0,说明没有一堆的,全是另一种操作,这一种是看操作个数,如果是奇数,先手胜。

    2.a 为 1,说明只有只有一堆 为1的, 这个是先手必胜,因为如果 b是偶数,那么就可以先合并,如果是 b 是奇数,就是直接拿掉。

    3.b 为 1,说明最后那个也只剩下一个了,要把 b 放到 a 上。

    3.从 a 中拿走一个。

    4.从 b 中拿走一个。

    5.合并 a 中的一个石子到 b。

    6.合并 a 中的两个石子,然后就不再是一个了,就得放到 b 上。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <sstream>
    #include <list>
    #define debug() puts("++++");
    #define gcd(a, b) __gcd(a, b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const double inf = 0x3f3f3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 1000 + 5;
    const int mod = 10;
    const int dr[] = {-1, 0, 1, 0};
    const int dc[] = {0, 1, 0, -1};
    const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline bool is_in(int r, int c) {
      return r >= 0 && r < n && c >= 0 && c < m;
    }
    
    int dp[55][50*maxn];
    
    int dfs(int a, int b){
      int &ans = dp[a][b];
      if(ans != -1)  return ans;
      if(0 == a)  return ans = b & 1;
      if(1 == a)  return ans = 1;
      if(1 == b)  return ans = dfs(a+1, b-1);  //take the second to the one
      if(!dfs(a-1, b))  return ans = 1;  //from the one select one
      if(b > 0 && !dfs(a, b-1))  return ans = 1;  //from the second select one
      if(b > 0 && !dfs(a-1, b+1))  return ans = 1;  //unit the one to the second
      if(a > 1 && !dfs(a-2, b ? b+3 : b+2))  return ans = 1;  //unit the two from the one to the second
      return ans = 0;
    }
    
    int main(){
      int T;  cin >> T;
      memset(dp, -1, sizeof dp);
      for(int kase = 1; kase <= T; ++kase){
        scanf("%d", &n);
        int a = 0, b = 0;
        for(int i = 0; i < n; ++i){
          int x;
          scanf("%d", &x);
          if(1 == x)  ++a;
          else b += x + 1;
        }
        printf("Case #%d: %s
    ", kase, dfs(a, b-1) ? "Alice" : "Bob");
      }
      return 0;
    }
    

      

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/7248862.html
Copyright © 2011-2022 走看看