码迷,mamicode.com
首页 > 其他好文 > 详细

ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)

时间:2018-09-18 20:43:42      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:ems   set   names   color   fine   正数   lan   long   bad   

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;
}

 

ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)

标签:ems   set   names   color   fine   正数   lan   long   bad   

原文地址:https://www.cnblogs.com/fht-litost/p/9671032.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!