我们可以轻易地发现,如果只出对子的话,答案是已经确定了的,所以我们可以只用考虑出顺子的情况,用DFS枚举顺子,然后更新答案。
剩下值得注意的就是题目的所给条件了,就是注意出牌规则。
这份代码只过了官方数据,还是有可能被卡掉的,因为官方数据是完全随机的。欢迎dalao们指正。
#include<bits/stdc++.h>
using namespace std;
int T,n,x,y,mn;
int cnt[20],tmp[5];
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
int x=0,b=1;
char c=nc();
for(;!(c<='9'&&c>='0');c=nc())if(c=='-')b=-1;
for(;c<='9'&&c>='0';c=nc())x=x*10+c-'0';
return x*b;
}
inline int update()
{
memset(tmp,0,sizeof(tmp));
for(int i=3;i<=16;i++)if(cnt[i])
if(cnt[i]<3)tmp[2]++;else tmp[cnt[i]]++;
return tmp[3]+tmp[4]+max(tmp[2]-tmp[3]-tmp[4]*2,0);
}
inline void DFS(int stp)
{
int x=update();
if(mn>stp+x)mn=stp+x;
for(int i=3;i<=14;i++)
if(cnt[i]>=1)
for(int j=i+1;j<=14&&cnt[j]>=1;j++)
if(j-i+1>=5)
{
for(int k=i;k<=j;k++)cnt[k]-=1;
DFS(stp+1);
for(int k=i;k<=j;k++)cnt[k]+=1;
}
for(int i=3;i<=14;i++)
if(cnt[i]>=2)
for(int j=i+1;j<=14&&cnt[j]>=2;j++)
if(j-i+1>=3)
{
for(int k=i;k<=j;k++)cnt[k]-=2;
DFS(stp+1);
for(int k=i;k<=j;k++)cnt[k]+=2;
}
for(int i=3;i<=14;i++)
if(cnt[i]>=3)
for(int j=i+1;j<=14&&cnt[j]>=3;j++)
if(j-i+1>=2)
{
for(int k=i;k<=j;k++)cnt[k]-=3;
DFS(stp+1);
for(int k=i;k<=j;k++)cnt[k]+=3;
}
}
int main()
{
freopen("in.txt","r",stdin);
T=read(),n=read();
while(T--)
{
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
x=read(),y=read();
if(x==1)cnt[14]++;
else if(x==2)cnt[15]++;
else if(x==0)cnt[16]++;
else cnt[x]++;
}
mn=~0u>>1;
DFS(0);
printf("%d\n",mn);
}
return 0;
}