zoukankan      html  css  js  c++  java
  • hdu-4753-Fishhead’s Little Game-记忆化搜索

    网赛的一道题目,当时没做出来。

    由题意可知,最多只有12条边未知。

    所以最多只有(1<<12)种状态。

    所以记忆化搜索这种状态下,枚举添加任意一条边之后的状态的最优值。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    int dp[10001];
    int visit[10001];
    int vis[25];
    int oth[25];
    int ts;
    int num(int vist[])
    {
        int i;
        int sum=0;
        for(i=1;i<=9;i++)
        {
            if(vist[i]&&vist[i+3]&&vist[i+12+(i-1)/3]&&vist[i+13+(i-1)/3])sum++;
        }
        return sum;
    }
    int dos(int x)
    {
        int sum=0,i;
        int vist[26];
        for(i=0;i<=24;i++)vist[i]=0;
        for(i=1;i<=ts;i++)
        {
            if(x&(1<<(i-1)))
            {
                vist[oth[i-1]]=1;
            }
        }
        for(i=1;i<=24;i++)
        {
            if(vis[i])vist[i]=1;
        }
        sum=num(vist);
        return sum;
    }
    int dfs(int x)
    {
        if(visit[x]!=-1)return visit[x];
        int ans=0;
        for(int i=1;i<=ts;i++)
        {
            if(!(x&(1<<(i-1))))
            {
                int y;
                y=x+(1<<(i-1));
                int ss;
                ss=dfs(y);
                ans=max(9-dp[x]-ss,ans);
            }
        }
        visit[x]=ans;
        return ans;
    }
    int main()
    {
        int T,i,n,a,b;
        int cas;
        int anum,bnum,s;
        cas=0;
        scanf("%d",&T);
        while(T--)
        {
            cas++;
            anum=bnum=0;
            s=0;
            scanf("%d",&n);
            memset(vis,0,sizeof(vis));
            memset(visit,-1,sizeof(visit));
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&a,&b);
                if(a>b)swap(a,b);
                if(b-a==4)ts=12+a;
                else ts=a-a/4;
                vis[ts]=1;
                if(i%2==0)
                {
                    anum+=num(vis)-s;
                }
                else bnum+=num(vis)-s;
                s=num(vis);
            }
            ts=0;
            for(i=1;i<=24;i++)if(vis[i]==0)oth[ts++]=i;
            for(i=0;i<(1<<ts);i++)dp[i]=dos(i);
            int have;
            have=9-s;
            int fs;
            fs=dfs(0);
            //printf("%d %d %d %d
    ",anum,bnum,have,fs);
            printf("Case #%d: ",cas);
            if(n%2==0)
            {
                if(anum+fs>bnum+have-fs)cout<<"Tom200"<<endl;
                else cout<<"Jerry404"<<endl;
            }
            else
            {
                if(anum+have-fs>bnum+fs)cout<<"Tom200"<<endl;
                else cout<<"Jerry404"<<endl;
            }
        }
        return 0;
    }
    


  • 相关阅读:
    LeetCode-195
    中文屋子与图灵测试谁对?
    leedcode-122
    Java 网络编程
    Java File类与IO流
    Java 异常
    Java 多线程
    Java Collection集合
    Java 常用API (第二部分)
    Java 日期时间与unix时间戳之间转换
  • 原文地址:https://www.cnblogs.com/riskyer/p/3395263.html
Copyright © 2011-2022 走看看