[HDU 5005 Compromise] 阅读理解+记忆化搜索

题目

http://acm.hdu.edu.cn/showproblem.php?pid=5005

分析

第一问十分容易,可以采用记忆化搜索,对AMB的节点,在他的子节点中选取一个AMD得分最高的(由于得分都是不同的,因此节点唯一),那么对于xiaoqiang的节点也在子节点中选取一个得分最多的进行决策,最后得出答案。

对于第二问,我们可以发现N只有200,并且得分都是不同的,我们可以枚举最后xiangqiang的最高得分,对于xiaoqiang的节点,分两种情况讨论,如果子节点中有得分等于枚举出的得分的节点,为了得到这个答案,就必须选这个子节点;如果没有,那么我们就要让AMD的得分尽量少,使AMD决策时有更大的可能选择xiaoqiang得分为枚举的答案,因此在子节点中选择AMD得分最少的点。对于AMD的节点,决策不变,选择子节点中AMD得分最大的点。

代码

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define pf printf
#define sf scanf
#define Fill(a,b) memset(a,b,sizeof(a))
const int N = 222;
struct st
{
    int a,x,tot;
    int nxt[202];
    char turn;
};
int f[N],g[N];
st a[N];
int n;
void solve(int x)
{
    if (f[x] != -1 || g[x] != -1) return;
    int maxa = 0,maxx = 0;
    for (int i = 1; i <= a[x].tot; i++)
    {
        int y = a[x].nxt[i];
        solve(y);
        if (a[x].turn == 'X')
        {
            if (maxx < g[y])
            {
                maxx = g[y];
                maxa = f[y];
            }
        }
        else
        {
            if (maxa < f[y])
            {
                maxa = f[y];
                maxx = g[y];
            }
        }
    }
    f[x] = maxa; g[x] = maxx;
}
void dfs(int x,int va,int vx)
{
  //  cout<<x<<" "<<a[x].turn<<endl;
    //cout<<x<<endl;
    //cout<<f[x]<<" "<<g[x]<<endl;
    if (f[x] != -1 || g[x] != -1) return;
    if (a[x].turn == 'X')
    {
        bool flag = 0;
     //   cout<<x<<endl;
        for (int i = 1; i <= a[x].tot; i++)
        {
            int y = a[x].nxt[i];
          //  if (x == 5) cout<<y<<endl;
            dfs(y,va,vx);
            if (g[y] == vx) flag = 1;
        }
        //if (x == 5) cout<<flag<<endl;
        if (flag)
        {
            f[x] = va;
            g[x] = vx;
            return;
        }
        int maxa = 1e9,maxx;
        for (int i = 1; i <= a[x].tot; i++)
        {
            int y = a[x].nxt[i];
            if (maxa > f[y])
            {
                maxa = f[y];
                maxx = g[y];
            }
        }
        f[x] = maxa; g[x] = maxx;
    }
    else
    {
        int maxa = 0,maxx = 0;
        for (int i = 1; i <= a[x].tot; i++)
        {
            int y = a[x].nxt[i];
            dfs(y,va,vx);
            if (maxa < f[y])
            {
                maxa = f[y];
                maxx = g[y];
            }
        }
        f[x] = maxa; g[x] = maxx;
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    sf("%d",&T);
    for (int TT = 1; TT <= T; TT++)
    {
        sf("%d",&n);
        for (int i = 1; i <= n; i++)
        {
            int x;
            sf("%d",&x);
            //cout<<i<<" "<<x<<endl;
            if (x == 0)
            {
                sf("%d%d",&a[i].a,&a[i].x);
                a[i].tot = 0;
            }
            else
            {
               // cout<<x<<endl;
                a[i].tot = 0;
                for (int j = 1; j <= x; j++) sf("%d",&a[i].nxt[++a[i].tot]);
                char ch;
                sf("%c%c",&ch,&a[i].turn);
                //cout<<a[i].turn<<endl;
            }
        }
        Fill(f,-1); Fill(g,-1);
        for (int i = 1; i <= n; i++)
            if (a[i].tot == 0) f[i] = a[i].a,g[i] = a[i].x;
        solve(1);
        int ans1 = g[1],ans2 = 0;
        for (int i = 1; i <= n; i++)
            if (a[i].tot == 0)
            {
                int va = a[i].a,vx = a[i].x;
               // va = 100; vx = 101;
              // cout<<va<<" "<<vx<<endl;
                Fill(f,-1); Fill(g,-1);
                for (int j = 1; j <= n; j++)
                    if (a[j].tot == 0) f[j] = a[j].a,g[j] = a[j].x;
                dfs(1,va,vx);
                if (g[1] == vx) ans2 = max(ans2,g[1]);
            }
        pf("%d %d\n",ans1,ans2);
    }
    return 0;
}


你可能感兴趣的:([HDU 5005 Compromise] 阅读理解+记忆化搜索)