我的和牌距离似乎是对的,但第一张牌错了。
int dis_to_do(int &first,int count)
{
//cout<<count<<"\n";
memset(dp,0x3f,sizeof(dp));
dp[3][0][0][0][0]=0;
for(int i=3;i<=36;i++)
for(int j=0;j<=count;j++)//需要的附露数
for(int k=0;k<=1;k++)
for(int l=0;l<=2&&l+j<=count;l++)
{
for(int r=0;r<=2&&l+r+j<=count;r++)
{
if(dp[i][j][k][l][r]>20)continue;//无效
for(int x=l+r;x<=4;x++)
{
int nx=max(0,x-siz[i+1])+dp[i][j][k][l][r];
int ny=(siz[i+1]>x ? (i+1) : dis[i][j][k][l][r]);
int now=x-l-r;
if(now>=2&&(!k))
doit(dp[i+1][j+l][1][r][now-2],dis[i+1][j+l][1][r][now-2],nx,ny);//组了一对
if(now>=3&&(j+l+r+1<=count))
doit(dp[i+1][j+1+l][k][r][now-3],dis[i+1][j+1+l][k][r][now-3],nx,ny);//多一个杠
if(now<=2)//三个以上全当杠就好了,得保证顺子合法
doit(dp[i+1][j+l][k][r][now],dis[i+1][j+l][k][r][now],nx,ny);//全组了顺子
}
if(i<=9||i==18||i==27||i==36||i==10||i==19||i==28||i==37)break;//每组的第一张牌不能组
}
if(i<=10||i==19||i==28||i==37)break;
}
first=dis[37][count][1][0][0];
return dp[37][count][1][0][0];
}
其中,1,2,3,…,37 对应的牌如下:
const string num_to_card[]=
{
"NULL","PASS","REVERSE","DOUBLE",//3
"Z","F","B","N","W","S","E",//10
"9S","8S","7S","6S","5S","4S","3S","2S","1S",//19
"9P","8P","7P","6P","5P","4P","3P","2P","1P",//28
"9M","8M","7M","6M","5M","4M","3M","2M","1M"//37
};