noip斗地主

Posted yinwuxiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; 
}

 

以上是关于noip斗地主的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4325: NOIP2015 斗地主

[BZOJ 4325][NOIP 2015] 斗地主

NOIP2015斗地主

BZOJ-4325: NOIP2015 斗地主 (搜索神题)

[NOIp 2015]斗地主

斗地主[NOIP2015]