Analysis
又一道恶心到我的题,不亚于之前的楼梯dp
类似之前做过的斗地主,枚举打哪一张牌并统计打这张牌的胡牌数
比较恶心也不好打,一百行,第一次80分大概靠rp。改一下就A了
Code
#include <cstdio>
#include <cstring>
using namespace std;
struct chp{int typ,num;}c[10001];
int card[3][101],v[3][101],mx=0,tmp,ans,cnt=0;
bool vis [3][101];
char s[421];
void dfs(int dep,int tot,bool lxf)
{
if (tot==2&&lxf)
{
for (int i=0;i<3;i++)
for (int j=1;j<=9;j++)
{
if (card[i][j]&&card[i][j+1])
{
if (j>1&&!vis[i][j-1])
tmp+=v[i][j-1],vis[i][j-1]=true;
if (j+1<9&&!vis[i][j+2])
tmp+=v[i][j+2],vis[i][j+2]=true;
}
if (card[i][j]==2&&!vis[i][j])
tmp+=v[i][j],vis[i][j]=true;
if (card[i][j]&&card[i][j+2])
{
if (j<9&&!vis[i][j+1])
tmp+=v[i][j+1],vis[i][j+1]=true;
}
}
return;
}
if (tot==1&&!lxf)
{
for (int i=0;i<3;i++)
for (int j=1;j<=9;j++)
if (card[i][j]&&!vis[i][j])
tmp+=v[i][j],vis[i][j]=true;
return;
}
for (int i=0;i<3;i++)
for (int j=1;j<=9;j++)
{
if (card[i][j]>=3)
{
card[i][j]-=3;
dfs(dep+1,tot-3,lxf);
card[i][j]+=3;
}
if (card[i][j]&&card[i][j+1]&&card[i][j+2])
{
card[i][j]--;
card[i][j+1]--;
card[i][j+2]--;
dfs(dep+1,tot-3,lxf);
card[i][j]++;
card[i][j+1]++;
card[i][j+2]++;
}
if (card[i][j]>=2&&!lxf)
{
card[i][j]-=2;
dfs(dep+1,tot-2,true);
card[i][j]+=2;
}
}
}
int main()
{/*
freopen("mahjong.in","r",stdin);
freopen("mahjong.out","w",stdout);*/
for (int i=0;i<3;i++)
for (int j=1;j<=9;j++)
v[i][j]=4;
for (int i=1;i<=14;i++)
{
scanf("%s",s);
for (int j=0;j<=strlen(s);j+=3)
{
int typ;
if (s[j+1]=='s')
typ=2;
if (s[j+1]=='w')
typ=1;
if (s[j+1]=='p')
typ=0;
card[typ][s[j]-'0']++;
v[typ][s[j]-'0']--;
c[++cnt]=(chp){typ,s[j]-'0'};
}
}
int rec;
for (int i=1;i<=cnt;i++)
if (card[c[i].typ][c[i].num])
{
memset(vis,false,sizeof(vis));
tmp=0;
card[c[i].typ][c[i].num]--;
dfs(1,13,false);
card[c[i].typ][c[i].num]++;
if (tmp>mx)
{
mx=tmp;
rec=i;
}
}
printf("%d %d\n",rec,mx);
return 0;
}