对抗搜索/dp-hdu-4753-Fishhead’s Little Game

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

题目链接:

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

题目意思:

在3*3的方格中,有4*4=16个点,标号分别为1~16,A、B两人轮流玩游戏,每次可以添加一条边(相邻节点),如果恰好能够凑成一个边长为1的正方形则得一分,两个的话得2分。给定两人放的n边后,求最终格局谁会胜。

解题思路:

状态压缩+对抗搜索。(对抗搜索做少了)

和今年通话邀请赛这题很像:http://blog.csdn.net/cc_again/article/details/10284769

除去给定的n条边,还剩下不到12条边S,所以可以状态压缩,dp[i]表示,S中放了边的状态为i的情况下,先走还能获得的最大分数。

每次dfs维护一个剩余的分数sum,表示当前状态下能获得的最大分数,dp[s]=max(sum-走一步后对手获得的最大分数);

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3fffffff
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

int dp[1<<12];//dp[i]表示走了i状态的边,还能获得的最大分数
bool hav[20][20];
int n;

bool iscan(int aa,int bb,int b,int a) //能否围城正方形
{
    if(hav[aa][bb]&&hav[bb][b]&&hav[b][a]&&hav[a][aa])
        return true;
    return false;
}

struct Edge
{
    int x,y;
};
vector<Edge>myv;

int ok1(int a,int b)//横着的情况
{

    int aa=a-4,bb=b-4,res=0;

    if(aa>=0&&bb>=0) //上
    {
        if(iscan(aa,bb,b,a))
            res++;
    }
    aa=a+4,bb=b+4;
    if(aa<16&&bb<16) //下
    {
        if(iscan(aa,bb,b,a))
            res++;
    }
    return res;
}
int ok2(int a,int b)
{
    int res=0;
    int aa,bb;

    aa=a-1,bb=b-1;
    if(bb%4!=3) //aa可能为负数 左
    {
        if(iscan(a,b,bb,aa))
            res++;
    }
    aa=a+1,bb=b+1; //右
    if(aa%4)
    {
        if(iscan(a,b,bb,aa))
            res++;
    }
    return res;
}
int dfs(int ord,int s,int sum)
{
    if(ord==25||sum<=0) //分数已经得完了
        return 0;
    if(dp[s]!=-1) //记忆话搜索
        return dp[s];
    int res=0;
    for(int i=0;i<myv.size();i++)
    {
        if((1<<i)&s)
            continue;
        hav[myv[i].x][myv[i].y]=true;
        hav[myv[i].y][myv[i].x]=true;
        if(myv[i].x==myv[i].y-1) //行
            res=max(res,sum-dfs(ord+1,s|(1<<i),sum-ok1(myv[i].x,myv[i].y)));
        else
            res=max(res,sum-dfs(ord+1,s|(1<<i),sum-ok2(myv[i].x,myv[i].y)));
        hav[myv[i].x][myv[i].y]=false;
        hav[myv[i].y][myv[i].x]=false;
    }
    dp[s]=res;
    return res;
}
int main()
{
   int t;

   scanf("%d",&t);
   for(int ca=1;ca<=t;ca++)
   {
       scanf("%d",&n);
       memset(hav,false,sizeof(hav));
       myv.clear();
       int pa=0,pb=0,a,b;

       for(int i=1;i<=n;i++)
       {
           scanf("%d%d",&a,&b);
           a--,b--;
           hav[a][b]=hav[b][a]=true;
           if(a>b)
            swap(a,b);
           if(a==b-1) //在同一行
           {
               if(i&1)
                    pa+=ok1(a,b);
               else
                    pb+=ok1(a,b);
           }
           else//同一列
           {
               if(i&1)
                    pa+=ok2(a,b);
               else
                    pb+=ok2(a,b);
           }
       }
       for(int i=0;i<16;i++) //统计剩下的边
            for(int j=i+1;j<16;j++)
            {
                if(hav[i][j])
                    continue;
                if(i==j-1&&j%4)
                {
                    Edge p;
                    p.x=i,p.y=j;
                    myv.push_back(p);
                }
                if(i==j-4)
                {
                    Edge p;
                    p.x=i,p.y=j;
                    myv.push_back(p);
                }
            }
        //printf("%d %d\n",pa,pb);
        memset(dp,-1,sizeof(dp));
        if(n<24)
        {
            if((n+1)&1) //当前谁先走
            {
                pa+=dfs(n+1,0,9-pa-pb);
                pb=9-pa;
            }
            else
            {
                pb+=dfs(n+1,0,9-pa-pb);
                pa=9-pb;
            }
        }
        //printf("ljdj\n");
        //printf("%d %d\n",pa,pb);
        printf("Case #%d: %s\n",ca,pa>=5?"Tom200":"Jerry404");
   }
   return 0;
}


对抗搜索(极大极小值搜索 http://web.cs.ucla.edu/~rosen/161/notes/alphabeta.html http://web.cs.ucla.edu/~rosen/161/notes/minimax.html 读完上边的文章之后应该就差不多了。 附上学长给的图 这两张就是伪代码和搜索的过程。 在这里记录一下我的理解:这个搜索过程是在一颗决策树上进行的,两方我们分别记为max 和... 阅读详情

相关推荐

UVALIVE 7505 Hungry Game of Ants DP

EC-FInal的题。。要是场上出了就好了。。。 题意:有N只蚂蚁玩饥饿游戏,在一个x轴上,第i只蚂蚁在坐标i上,重量为i,现在蚂蚁可以选择向左走或向右走,当两只蚂蚁相遇时大蚂蚁吃掉小蚂蚁,重量增加小蚂蚁的重量,如果重量相同,左边的蚂蚁吃掉右边的蚂蚁,给出N,K,问第K只蚂蚁最后留下的情况数。 数据范围: N=1 K 解题:对于第N只蚂蚁,如果他想获胜,那么最后一个向左走的蚂蚁的前缀和必须小

translata的博客 1380

ACM 2017 南宁区域赛 Rake it in(对抗搜索)

https://nanti.jisuanke.com/t/19975 题目大意:     Alice和Bob在玩一种名为“Rake It In”的游戏,起初有一个4*4的棋盘,每一格为一个1~10的整数,两人轮流行动,各自k次,行动者选择棋盘中某一个2*2的区域,将这四个元素求和,加到最终答案中,并将四个元素按逆时针旋转90度,Alice先行。Alice的目标是最大化最后的答案,Bob相...

hxxjxw的博客 599

[递推dp] zoj 3747 Attack on Titans

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5170 Attack on Titans Time Limit: 2 Seconds      Memory Limit: 65536 KB Over centuries ago, mankind faced a new enemy, th

cc_again的专栏 8042

Codeforces 474 C. Captain Marmot

4*4*4*4暴力+点的旋转+判断正方型 C. Captain Marmot time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Captai

码代码的猿猿 1301

codeforces 474D DP

Flowers    CodeForces - 474D 题目原文:We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all know, Marmot eats flowers. At every dinner he eats some

12Dong的博客 566

HDU 4753 Fishhead’s Little Game(对抗搜索\DP+状态压缩)

很水的状态压缩+对抗搜索,说白了就是dp,记忆化搜索即可。。。 什么逗比状态,中途差点就睡着了。。。 1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 5 6 int edge[25][2]; 7 int mp[17]...

dechi5213的博客 170

HDU 4753 Fishhead’s Little Game (对抗搜索)

题意:在3*3的方格中,有4*4=16个点,标号分别为1~16,A、B两人轮流玩游戏,每次可以添加一条边(相邻节点),如果恰好能够凑成一个边长为1的正方形则得一分,两个的话得2分。现在给定两人已经连接的n条边后,求最终格局谁会胜。 因为总计只有24条边,而且只能剩下0--12条边,所以状态压缩记录好剩下还没走好的步数,dp[i]表示状态i下,当前玩家能获得的最大分数。 如何处理连边,方

Paradiser 1462

D. Flowers Codeforces Round #271(div2)

D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output We saw the little game Marmot made for Mole's

ACway的专栏 1523

ACM-ICPC 2017 Asia Nanning I.Rake It In (对抗搜索

题目链接 The designers have come up with a new simple game called “Rake It In”. Two players, Alice and Bob, initially select an integer k and initialize a score indicator. An 4 \times 44×4 board is creat...

limn204的专栏 864

DP专辑】ACM动态规划总结

动态规划一直是ACM竞赛中的重点

cc_again的专栏 2万+

[dp] Codeforces 429B B. Working out

题目链接: http://codeforces.com/problemset/problem/429/B PROBLEMS SUBMIT STATUS STANDINGS CUSTOM TEST B. Working out time limit per test 2 seconds memory li

cc_again的专栏 9701

递推计数-hdu-4747-Mex

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4747 题目大意: 给n个数,求所有区间内没有出现的最小非负整数和。 解题思路: 首先感谢大神博客:http://www.cnblogs.com/xin-hua/p/3325154.html可以解释的太少了。 我再解释一遍。 首先要明白,以i结束的所有区间的值的和记为f[i]肯定不超

cc_again的专栏 7117

组合dp hdu-4489-The King’s Ups and Downs

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4489 题目意思: 给一个n,求n个高矮不同的人排成一排使得高、矮依次排列的种数。 解题思路: 组合dp. 对于n个人,设其高度分别为1,2,3,,,,,n.   对于第n个人,假设前面的n-1个人已经放好了。第n个人有n个位置可放,对于任一位置j,显然第n个人的身高n大于前n-1个

cc_again的专栏 4967

[高精度+递推] uva 10328 Coin Toss

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1269 Toss is an important part of any event. When everything becomes equal toss is the ulti

cc_again的专栏 4667

计数dp-hdu-4054-Number String

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4055 题目大意: 给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D表示当前的数字小于前面一位的数字,?表示当前位既可以小于又可以大于。 问1~n的排列中有多少个满足该字符串。 解题思路: 计数dp. dp[i][j]表示长度为i字符串,最后一个数为

cc_again的专栏 4467

区间dp+输出方案 poj-1141-Brackets Sequence

题目链接: http://poj.org/problem?id=1141 题目大意: 给一个由[,],{,}组成的字符串序列,求增加最少的字符,使该序列能够匹配,并输出最后的方案。 解题思路: 区间dp.dp[i][j]表示从i~j 所需的最少的字符使之能匹配,转移的话要么是头尾匹配直接加中间,要么分成两段。 不过要输出到达路径,所以在用一个path[i][j]表示到达该路径时的选

cc_again的专栏 4285

区间dp-zoj3541-The Last Puzzle

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3541 题目大意: 在数轴上,有n个按钮,位置递增为d1,d2,..dn,每个按钮对应一个时间为t1,t2,...tn.每次每个按钮按下后,t1秒后会自动弹起来。每走单位距离花费单位时间,问以怎样的顺序按,能够保证所有 的按钮都能够被按下去。 解题思路

cc_again的专栏 3589

数位dp+LIS+状态压缩-hdu-4352-XHXJ's LIS

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4352 题目意思: 求区间L到R之间的数A满足A的的数位的最长自增序列的长度为K的数的个数。 解题思路: 数位dp+LIS+状态压缩 根据求LIS的nlogn的思想,由于k最多为10,也就是最长递增序列的长度最多为10,可以状态压缩10位,维护前面的已选的递增序列,并及时更新。 dp

cc_again的专栏 3471

区间dp-hdu-4745-Two Rabbits

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4745 题目意思: 给n个环状的数,A、B两人沿相反的方向走,每单位时间走一步,要求相同时间两人到达相同的数,且同一位置同一个人不能走两次,走过的位置不能越过。 解题思路: 根据回文非连续序列的性质,从前往后,和从后往前序列是一样的,所以只用求出区间内最长的回文序列即可,又由于是环状,所

cc_again的专栏 3406
上一篇: 递推计数-hdu-4747-Mex
下一篇: 并查集+二分-hdu-4750-Count The Pairs
Accagain
博客等级 码龄14年 376粉丝 316原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值