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斗地主的主要内容,如果未能解决你的问题,请参考以下文章