• noip斗地主


    题解:

    5分钟看题

    25分钟码完

    然后调了一下

    样例1s???

    好吧我把只出一张牌当成决策了。。

    判断了一下前面没有出牌再考虑这个决策(是不是傻逼??)

    交上去65

    于是愉快的改状压

    改到一半的时候想到 没有办法出牌就直接return了。。

    交上去 a了

    继续写状压

    的确状压还是快了10倍+的

    不过毕竟没有用什么贪心能100ms出解就不错了。。

    好像很多人都是用贪心的。。

    但是贪心正确性显然是错的啊。。。

    好像说3连是没用的,那显然全是三连就一步啊。。。

    先打4带2那要是都是一个4张其他都是连着3张显然也不对啊。。。

    加强版那题 4个1可以当成2对 这题目都没说清楚。。

    代码:

    暴力:

    // luogu-judger-enable-o2
    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int 
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    // J 11 Q 12 K 13 A 14 2 15
    int T,n,a[30],ans,p;
    void dfs(int n,int cnt)
    {
      bool tt=0;
      p++;
      if (cnt>=ans) return;
      ans=min(ans,cnt+n);
      if (!n) return;
      int sum[15];
      sum[2]=0;
      rep(i,3,14) if (a[i]) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+5-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j) a[k]--;
          tt=1;
          dfs(n-(j-i+1),cnt+1);
          rep(k,i,j) a[k]++;
        }
      rep(i,3,14) if (a[i]>1) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+3-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j) a[k]-=2;
          tt=1;
          dfs(n-(j-i+1)*2,cnt+1);
          rep(k,i,j) a[k]+=2; 
        }
      rep(i,3,14) if (a[i]>2) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+2-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j) a[k]-=3;
          tt=1;
          dfs(n-(j-i+1)*3,cnt+1);
          rep(k,i,j) a[k]+=3;
        }
      rep(i,3,15)
        if (a[i]==4)
        {
          a[i]-=4;
          rep(i1,3,17)
            rep(i2,i1+1,17)
            {
              if (a[i1]&&a[i2])
              {
                a[i1]--; a[i2]--;
                tt=1;
                dfs(n-6,cnt+1);
                a[i1]++; a[i2]++;
                if (a[i1]>1&&a[i2]>1)
                {
                  a[i1]-=2; a[i2]-=2;
                  dfs(n-8,cnt+1);
                  a[i1]+=2; a[i2]+=2;
                }
              }
            }
          a[i]+=4;  
        }
      if (a[16]&&a[17])
      {
        tt=1;
        a[16]=a[17]=0; dfs(n-2,cnt+1);
        a[16]=a[17]=1;
      }
        rep(i,3,15)
        if (a[i]==4)
        {
          tt=1;
          a[i]=0; dfs(n-4,cnt+1);
          a[i]=4;
        }
      rep(i,3,15)
        if (a[i]>=3)
        {
          tt=1;
          a[i]-=3; dfs(n-3,cnt+1);
          rep(j,3,17)
          {
            if (a[j])
            {
              a[j]--; dfs(n-4,cnt+1); a[j]++;
              if (a[j]>1)
              {
                a[j]-=2; dfs(n-5,cnt+1); a[j]+=2;
              }
            }
          }
          a[i]+=3;
        }
      rep(i,3,15)
        if (a[i]>=2)
        {
          tt=1;
          a[i]-=2; dfs(n-2,cnt+1);
          a[i]+=2;
        }
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("2.out","w",stdout); 
      ios::sync_with_stdio(false);
      cin>>T>>n;
      rep(sb,1,T)
      {
        int x,y;
        me(a);
        rep(i,1,n) 
        {
          cin>>y>>x;
          if (y==0)
            if (x==1) a[16]++;
            else a[17]++;
          else
          {
            int kk=y;
            if (kk==1) kk=14;
            if (kk==2) kk=15;
            a[kk]++;
          }
        }
        ans=n;
        dfs(n,0);
        cout<<ans<<endl;
      }
     // cout<<p<<endl;
      return 0; 
    }

    状压(记忆化搜索):

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int 
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    // J 11 Q 12 K 13 A 14 2 15
    int T,n,a[30],ans,p;
    const int N=9e6;
    int f[N];
    int o[30][5];
    queue<int> q; 
    void minn(int &x,int y)
    {
      if (x>y) x=y;
    }
    int dfs(int n,int cnt,int now)
    {
      if (f[now])
      {
        ans=min(ans,cnt+f[now]); 
        return(f[now]);
      }
      int tmp=now; f[now]=n; q.push(now);
      p++;
        ans=min(ans,cnt+n);
      if (!n) return(0);
      if (cnt>=ans) return(100);
      int sum[15];
      sum[2]=0;
      rep(i,3,14) if (a[i]) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+5-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j)
          { 
            now^=1<<(o[k][a[k]]-1);
            a[k]--;
          }
          minn(f[tmp],1+dfs(n-(j-i+1),cnt+1,now));
          rep(k,i,j) a[k]++; now=tmp;
        }
      rep(i,3,14) if (a[i]>1) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+3-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j)
          { 
            now^=1<<(o[k][a[k]]-1);
            now^=1<<(o[k][a[k]-1]-1);
            a[k]-=2;
          }
          minn(f[tmp],1+dfs(n-(j-i+1)*2,cnt+1,now));
          rep(k,i,j) a[k]+=2; now=tmp;
        }
      rep(i,3,14) if (a[i]>2) sum[i]=sum[i-1]+1;
      else sum[i]=sum[i-1];
      rep(i,3,14)
        rep(j,i+2-1,14)
        {
          if (sum[j]-sum[i-1]!=j-i+1) break;
          rep(k,i,j)
          {
            now^=1<<(o[k][a[k]]-1);
            now^=1<<(o[k][a[k]-1]-1);
            now^=1<<(o[k][a[k]-2]-1);
            a[k]-=3;
          } 
          minn(f[tmp],1+dfs(n-(j-i+1)*3,cnt+1,now));
          rep(k,i,j) a[k]+=3; now=tmp;
        }
      rep(i,3,15)
        if (a[i]==4)
        {
          now^=1<<(o[i][4]-1);
          now^=1<<(o[i][3]-1);
          now^=1<<(o[i][2]-1);
          now^=1<<(o[i][1]-1);
          int tmp2=now;
          a[i]-=4;
          rep(i1,3,17)
            rep(i2,i1+1,17)
            {
              if (a[i1]&&a[i2])
              {
                now^=1<<(o[i1][a[i1]]-1);
                now^=1<<(o[i2][a[i2]]-1);
                a[i1]--; a[i2]--;
                minn(f[tmp],1+dfs(n-6,cnt+1,now));
                a[i1]++; a[i2]++; now=tmp2;
                if (a[i1]>1&&a[i2]>1)
                {
                  now^=1<<(o[i1][a[i1]]-1);
                  now^=1<<(o[i1][a[i1]-1]-1);
                  now^=1<<(o[i2][a[i2]]-1);
                  now^=1<<(o[i2][a[i2]-1]-1);
                  a[i1]-=2; a[i2]-=2;
                  minn(f[tmp],1+dfs(n-8,cnt+1,now));
                  a[i1]+=2; a[i2]+=2;
                  now=tmp2;
                }
              }
            }
          a[i]+=4; now=tmp;
        }
      if (a[16]&&a[17])
      {
        now^=1<<(o[16][1]-1);
        now^=1<<(o[17][1]-1);
        a[16]=a[17]=0; 
        minn(f[tmp],1+dfs(n-2,cnt+1,now));
        a[16]=a[17]=1;
        now=tmp;
      }
        rep(i,3,15)
        if (a[i]==4)
        {
          now^=1<<(o[i][4]-1);
          now^=1<<(o[i][3]-1);
          now^=1<<(o[i][2]-1);
          now^=1<<(o[i][1]-1);
          a[i]=0; minn(f[tmp],1+dfs(n-4,cnt+1,now));
          a[i]=4;
          now=tmp;
        }
      rep(i,3,15)
        if (a[i]>=3)
        {     
          now^=1<<(o[i][a[i]]-1);
          now^=1<<(o[i][a[i]-1]-1);
          now^=1<<(o[i][a[i]-2]-1);
          int tmp2=now;
          a[i]-=3; minn(f[tmp],1+dfs(n-3,cnt+1,now));
          rep(j,3,17)
          {
            if (a[j])
            {
              now^=1<<(o[j][a[j]]-1);
              a[j]--; 
              minn(f[tmp],1+dfs(n-4,cnt+1,now)); a[j]++; now=tmp2;
              if (a[j]>1)
              {
                now^=1<<(o[j][a[j]]-1);
                now^=1<<(o[j][a[j]-1]-1);
                a[j]-=2; 
                minn(f[tmp],1+dfs(n-5,cnt+1,now)); a[j]+=2;
                now=tmp2;
              }
            }
          }
          a[i]+=3; now=tmp;
        }
      rep(i,3,15)
        if (a[i]>=2)
        {
          now^=1<<(o[i][a[i]]-1);
          now^=1<<(o[i][a[i]-1]-1);
          a[i]-=2; 
          minn(f[tmp],1+dfs(n-2,cnt+1,now));
          a[i]+=2; now=tmp;
        }
      return(f[tmp]);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      ios::sync_with_stdio(false);
      cin>>T>>n;
      rep(sb,1,T)
      {
        while (!q.empty()) f[q.front()]=0,q.pop();
        int x,y;
        me(a);
        rep(i,1,n) 
        {
          cin>>y>>x;
          if (y==0)
            if (x==1) a[16]++,o[16][1]=i;
            else a[17]++,o[17][1]=i;
          else
          {
            int kk=y;
            if (kk==1) kk=14;
            if (kk==2) kk=15;
            a[kk]++,o[kk][a[kk]]=i;
          }
        }
        ans=n;
        dfs(n,0,(1<<n)-1);
        cout<<ans<<endl;
      }
     // cout<<p<<endl;
      return 0; 
    }
  • 相关阅读:
    /etc/vim/vimrc的一个的配置
    vim上下左右键输出A B
    数据结构-栈的实现之行编译器核心实现
    数据结构-栈的实现之括号匹配检测
    数据结构-栈的实现之数制转换
    数据结构-线性表的链式结构
    数据结构-栈的顺序结构两种方式
    简介
    数据结构-线性表的顺序结构
    NHibernate系列文章十六:使用程序集管理NHibernate项目(附程序下载)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9360513.html
Copyright © 2020-2023  润新知