【解题报告】洛谷P2668 斗地主
【解题报告】洛谷P2668 斗地主
题目链接
https://www.luogu.com.cn/problem/P2668
思路
大模拟+搜索
按照从顺子开始的顺序贪心,从三顺子先出,到双顺子,然后到顺子
然后出四带二,三带二,三带一,然后最后就是可以一次出完的那种了
这个题目呢贪心的思路想到不难,但是模拟出来及其考察代码能力
所以我就炸了
我代码能力超蒻的好不好
那是不是今年再出一个大模拟我就炸了
还有一个点就在于回溯
我们每次搜进去之后记得出来的时候回溯,以便搜索其他的状态,这样就比较方便了
强烈建议多练大模拟
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#define int long long
using namespace std;
int T,n,ans;
int a[20];
void dfs(int x)
{
if(x>=ans) return ;
int k=0;
for(int i=3;i<=14;i++)
{
if(a[i]==0) k=0;
else
{
k++;
if(k>=5)
{
for(int j=i;j>=i-k+1;j--)
a[j]--;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)
a[j]++;
}
}
}
k=0;
for(int i=3;i<=14;i++)
{
if(a[i]<=1) k=0;
else
{
k++;
if(k>=3)
{
for(int j=i;j>=i-k+1;j--)
a[j]-=2;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)
a[j]+=2;
}
}
}
k=0;
for(int i=3;i<=14;i++)
{
if(a[i]<=2) k=0;
else
{
k++;
if(k>=2)
{
for(int j=i;j>=i-k+1;j--)
a[j]-=3;
dfs(x+1);
for(int j=i;j>=i-k+1;j--)
a[j]+=3;
}
}
}
for(int i=2;i<=14;i++)
{
if(a[i]<=3)
{
if(a[i]<=2) continue;
a[i]-=3;
for(int j=2;j<=15;j++)
{
if(a[j]<=0||j==i) continue;
a[j]--;
dfs(x+1);
a[j]++;
}
for(int j=2;j<=14;j++)
{
if(a[j]<=1||j==i) continue;
a[j]-=2;
dfs(x+1);
a[j]+=2;
}
a[i]+=3;
}
else
{
a[i]-=3;
for(int j=2;j<=15;j++)
{
if(a[j]<=0||j==i) continue;
a[j]--;
dfs(x+1);
a[j]++;
}
for(int j=2;j<=14;j++)
{
if(a[j]<=1||j==i) continue;
a[j]-=2;
dfs(x+1);
a[j]+=2;
}
a[i]+=3;
a[i]-=4;
for(int j=2;j<=15;j++)
{
if(a[j]<=0||j==i) continue;
a[j]--;
for(int k=2;k<=15;k++)
{
if(a[k]<=0||k==j) continue;
a[k]--;
dfs(x+1);
a[k]++;
}
a[j]++;
}
for(int j=2;j<=14;j++)
{
if(a[j]<=1||j==i) continue;
a[j]-=2;
for(int k=2;k<=14;k++)
{
if(a[k]<=1||k==j) continue;
a[k]-=2;
dfs(x+1);
a[k]+=2;
}
a[j]+=2;
}
a[i]+=4;
}
}
for(int i=1;i<=15;i++)
{
if(a[i])
x++;
}
ans=min(ans,x);
}
signed main()
{
cin>>T>>n;
while(T--)
{
ans=1e9;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
if(x==0)
a[15]++;
else if(x==1)
a[14]++;
else
a[x]++;
}
dfs(0);
cout<<ans<<'\n';
}
return 0;
}
本博文为wweiyi原创,若想转载请联系作者,qq:2844938982