zoukankan      html  css  js  c++  java
  • Luogu2540 斗地主增强版(搜索+动态规划)

      单纯的暴搜似乎还是很好写的,然而过不了。出完顺子之后答案是可以dp出来的,于是大力搜然后大力dp就好了。

      dp时强行讨论完了几乎所有拆牌情况,理性愉悦一发。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int T,n,cnt[20],f[24][13][9][7][3],ans;//1:2 2~12:3~K 13:A 14 15:ghost
    void dfs(int k,int step);
    void threestraight(int k,int step)
    {
        for (int i=2;i<=12;i++)
        if (cnt[i]>=3&&cnt[i+1]>=3)
        {
            cnt[i]-=3,cnt[i+1]-=3;dfs(k-6,step+1);
            int t=i+1;while (cnt[t+1]>=3) t++,cnt[t]-=3,dfs(k-(t-i+1)*3,step+1);
            while (t>=i) cnt[t]+=3,t--;
        }
    }
    void twostraight(int k,int step)
    {
        for (int i=2;i<=11;i++)
        if (cnt[i]>=2&&cnt[i+1]>=2&&cnt[i+2]>=2)
        {
            cnt[i]-=2,cnt[i+1]-=2,cnt[i+2]-=2;dfs(k-6,step+1);
            int t=i+2;while (cnt[t+1]>=2) t++,cnt[t]-=2,dfs(k-((t-i+1)<<1),step+1);
            while (t>=i) cnt[t]+=2,t--; 
        }
    }
    void onestraight(int k,int step)
    {
        for (int i=2;i<=9;i++)
        if (cnt[i]&&cnt[i+1]&&cnt[i+2]&&cnt[i+3]&&cnt[i+4]) 
        {
            cnt[i]--,cnt[i+1]--,cnt[i+2]--,cnt[i+3]--,cnt[i+4]--;dfs(k-5,step+1);
            int t=i+4;while (t<13&&cnt[t+1]) t++,cnt[t]--,dfs(k-(t-i+1),step+1);
            while (t>=i) cnt[t]++,t--;
        }
    }
    void dfs(int k,int step)
    {
        int t[6]={0};
        for (int i=1;i<=13;i++) if (cnt[i]) t[cnt[i]]++;
        t[5]=cnt[14]+cnt[15];
        ans=min(ans,step+f[t[1]][t[2]][t[3]][t[4]][t[5]]);
        if (step+(k>0)>=ans) return;
        if (k==0) return;
        threestraight(k,step);
        twostraight(k,step);
        onestraight(k,step);
    }
    inline void update(int &x,int y){x=min(x,y);}
    void dp()
    {
        memset(f,42,sizeof(f));
        f[0][0][0][0][0]=0;
        for (int i=1;i<=n;i++)
            for (int x=0;x<=i;x++)
                for (int y=0;y*2<=i-x;y++)
                    for (int z=0;z*3<=i-x-y*2;z++)
                        for (int t=0;t*4<=i-x-y*2-z*3;t++)
                            for (int g=0;g<=min(2,i-x-y*2-z*3-t*4);g++)
                            {
                                if (x) update(f[x][y][z][t][g],f[x-1][y][z][t][g]+1);
                                if (y) update(f[x][y][z][t][g],f[x][y-1][z][t][g]+1);
                                if (y) update(f[x][y][z][t][g],f[x+1][y-1][z][t][g]+1);
                                if (z) update(f[x][y][z][t][g],f[x][y][z-1][t][g]+1);
                                if (z) update(f[x][y][z][t][g],f[x][y+1][z-1][t][g]+1);
                                if (z) update(f[x][y][z][t][g],f[x+1][y][z-1][t][g]+1);
                                if (t) update(f[x][y][z][t][g],f[x][y][z][t-1][g]+1);
                                if (t) update(f[x][y][z][t][g],f[x][y][z+1][t-1][g]+1);
                                if (t) update(f[x][y][z][t][g],f[x][y+1][z][t-1][g]+1);
                                if (t) update(f[x][y][z][t][g],f[x+1][y][z][t-1][g]+1);
                                if (g) update(f[x][y][z][t][g],f[x][y][z][t][g-1]+1);
                                if (g==2) update(f[x][y][z][t][g],f[x][y][z][t][g-2]+1);
                                //part 1 only one
                                if (z&&x) update(f[x][y][z][t][g],f[x-1][y][z-1][t][g]+1);
                                if (z&&y) update(f[x][y][z][t][g],f[x+1][y-1][z-1][t][g]+1);
                                if (z>=2) update(f[x][y][z][t][g],f[x][y+1][z-2][t][g]+1);
                                if (z&&g) update(f[x][y][z][t][g],f[x][y][z-1][t][g-1]+1);
                                if (t&&y) update(f[x][y][z][t][g],f[x+2][y-1][z][t-1][g]+1);
                                if (t>=2) update(f[x][y][z][t][g],f[x+1][y][z+1][t-2][g]+1);
                                if (t&&g) update(f[x][y][z][t][g],f[x][y][z][t-1][g-1]+1);
                                //part 2 three with one
                                if (z&&y) update(f[x][y][z][t][g],f[x][y-1][z-1][t][g]+1);
                                if (z>=2) update(f[x][y][z][t][g],f[x+1][y][z-2][t][g]+1);
                                if (z&&t) update(f[x][y][z][t][g],f[x][y+1][z-1][t-1][g]+1);
                                if (t&&y) update(f[x][y][z][t][g],f[x+1][y-1][z][t-1][g]+1);
                                if (t&&z) update(f[x][y][z][t][g],f[x+2][t][z-1][t-1][g]+1);
                                if (t>=2) update(f[x][t][z][t][g],f[x+1][y+1][z][t-2][g]+1);
                                //part 3 three with two
                                if (t)
                                {
                                    if (x>=2) update(f[x][y][z][t][g],f[x-2][y][z][t-1][g]+1);
                                    if (x&&g) update(f[x][y][z][t][g],f[x-1][y][z][t-1][g-1]+1);
                                    if (y) update(f[x][y][z][t][g],f[x][y-1][z][t-1][g]+1);
                                    if (y>=2) update(f[x][y][z][t][g],f[x+2][y-2][z][t-1][g]+1);
                                    if (y&&g) update(f[x][y][z][t][g],f[x+1][y-1][z][t-1][g-1]+1);
                                    if (z) update(f[x][y][z][t][g],f[x+1][y][z-1][t-1][g]+1);
                                    if (z&&x) update(f[x][y][z][t][g],f[x-1][y+1][z-1][t-1][g]+1);
                                    if (z&&y) update(f[x][y][z][t][g],f[x+1][y][z-1][t-1][g]+1);
                                    if (z>=2) update(f[x][y][z][t][g],f[x][y+1][z-2][t-1][g]+1);
                                    if (z&&g) update(f[x][y][z][t][g],f[x][y+1][z-1][t-1][g-1]+1);
                                    if (t>=2) update(f[x][y][z][t][g],f[x][y+1][z][t-2][g]+1);
                                    if (t>=3) update(f[x][y][z][t][g],f[x][y][z+2][t-3][g]+1);
                                    if (t>=2&&x) update(f[x][y][z][t][g],f[x-1][y][z+1][t-2][g]+1);
                                    if (t>=2&&y) update(f[x][y][z][t][g],f[x+1][y-1][z+1][t-2][g]+1);
                                    if (t>=2&&z) update(f[x][y][z][t][g],f[x][y+1][z][t-2][g]+1);
                                    if (t>=2&&g) update(f[x][y][z][t][g],f[x][y][z+1][t-2][g-1]+1);
                                    if (g>=2) update(f[x][y][z][t][g],f[x][y][z][t-1][g-2]+1);
                                    //part 4 four with one
                                    if (y>=2) update(f[x][y][z][t][g],f[x][y-2][z][t-1][g]+1);
                                    if (z>=2) update(f[x][y][z][t][g],f[x+2][y][z-2][t-1][g]+1);
                                    if (y&&z) update(f[x][y][z][t][g],f[x+1][y][z-1][t-1][g]+1);
                                    if (t>=2&&z) update(f[x][y][z][t][g],f[x+1][y+1][z-1][t-2][g]+1);
                                    if (t>=2) update(f[x][y][z][t][g],f[x][y][z][t-2][g]+1);
                                    if (t>=3) update(f[x][y][z][t][g],f[x][y+2][z][t-3][g]+1);
                                    //part 5 four with two
                                }
                            }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("2540.in","r",stdin);
        freopen("2540.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read(),n=read();
        dp();
        while (T--)
        {
            ans=n;memset(cnt,0,sizeof(cnt));
            for (int i=1;i<=n;i++)
            {
                int x=read(),y=read();
                if (x==0) cnt[y+13]++;
                else if (x==2) cnt[1]++;
                else if (x==1) cnt[13]++;
                else cnt[x-1]++;
            }
            dfs(n,0);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    BeautifulSoup使用总结
    使用python爬取整本《盗墓笔记》
    matplotlib使用总结
    模拟退火算法
    pandas实战——对星巴克数据的分析
    pandas使用总结
    JDBC之数据库操作基本步骤
    ERROR 2003: Can't connect to MySQL server on 'localhost' 的错误
    lammps 学习之:系统压力太大,导致原子丢失
    Idea中查看一个类的所有资料及其层级关系
  • 原文地址:https://www.cnblogs.com/Gloid/p/9786635.html
Copyright © 2011-2022 走看看