zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)

    https://nanti.jisuanke.com/t/31454

    题意

     两个人玩游戏,最初数字为m,有n轮,每轮三个操作给出a b c,a>0表示可以让当前数字加上a,b>0表示可以让当前数字减去b,c=1表示可以让当前数字乘-1,数字范围为[-100, 100],如果加/减出范围则直接等于边界,最终结果数字x>=R则为Good Ending,x<=L则为Bad Ending,否则Normal Ending,第一个人希望好结局,第二个人希望坏结局,如果没有办法就希望平局,每个人都做最优选择。求最终结果

    分析

     一开始题目没看懂啊。。很蒙,然后学弟就秒了。

    所以状态1000*200,考虑暴力求解。又是博弈题,那当然是记忆化搜索啦。把每个状态都搜一下,优先选赢,其次才是平局,最后才是输。

    因为分数可能为负数,所以这里加了个115变成正数来计算,方便得多。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define mod 1000000007
    int n, L, R, dp[1005][250];
    typedef struct Res{
        int x, y, z;
    }Res;
    Res s[1005];
    int Go(int x, int y, int t=0){
        if(x==1)  y = min(y+t, 215);
        else if(x==2)  y = max(y-t, 15);
        else  y += 2*(115-y);
        return y;
    }
    int dfs(int id, int x){
        int win, lose, done, temp;
        if(dp[id][x]<=1)
            return dp[id][x];
        if(id==n+1){
            if(x>=R)  return 1;
            if(x<=L)  return -1;
            return 0;
        }
        win = lose = done = 0;
        if(id%2){//先手,想造出GoodEnding
            if(s[id].x!=0){
                temp = dfs(id+1, Go(1, x, s[id].x));
                if(temp==1)  win = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  lose = 1;
            }
            if(s[id].y!=0){
                temp = dfs(id+1, Go(2, x, s[id].y));
                if(temp==1)  win = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  lose = 1;
            }
            if(s[id].z!=0){
                temp = dfs(id+1, Go(3, x));
                if(temp==1)  win = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  lose = 1;
            }
            if(win)  return dp[id][x] = 1;
            else if(done)  return dp[id][x] = 0;
            else  return dp[id][x] = -1;
        }else{
            if(s[id].x!=0){
                temp = dfs(id+1, Go(1, x, s[id].x));
                if(temp==1)  lose = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  win = 1;
            }
            if(s[id].y!=0){
                temp = dfs(id+1, Go(2, x, s[id].y));
                if(temp==1)  lose = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  win = 1;
            }
            if(s[id].z!=0){
                temp = dfs(id+1, Go(3, x));
                if(temp==1)  lose = 1;
                if(temp==0)  done = 1;
                if(temp==-1)  win = 1;
            }
            if(win)  return dp[id][x] = -1;
            else if(done)  return dp[id][x] = 0;
            else  return dp[id][x] = 1;
        }
    }
    int main(){
        int ans, m, i;
        scanf("%d%d%d%d", &n, &m, &R, &L);
        R += 115, L += 115;
        for(i=1;i<=n;i++)
            scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].z);
        memset(dp, 62, sizeof(dp));
        ans = dfs(1, m+115);
        if(ans==1) puts("Good Ending");
        else if(ans==-1) puts("Bad Ending");
        else puts("Normal Ending");
        return 0;
    }
  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9671032.html
Copyright © 2011-2022 走看看