1. 程式人生 > >【NOIP2015提高組Day1】鬥地主

【NOIP2015提高組Day1】鬥地主

簡單,暴力模擬

#include<cstdio>
#include<cstring>
using namespace std;
int a[18],f[18][18][18][18];
int ans;
int min(int x,int y){return x<y ? x:y;}
int biao(int a,int b,int c,int d)
{
    int s=a+b+c+d;
    if (a>0) s=min(s,f[a-1][b][c][d]+1);
    if (b>0) s=min(s,f[a][b-
1][c][d]+1); if (c>0) s=min(s,f[a][b][c-1][d]+1); if (d>0) s=min(s,f[a][b][c][d-1]+1); if (a>0 && c>1) s=min(s,f[a-1][b][c-2][d]+1); if (a>0 && d>1) s=min(s,f[a-1][b][c][d-2]+1); if (b>0 && c>0) s=min(s,f[a][b-1][c-1][d]+1); if (b>
0 && d>0) s=min(s,f[a][b-1][c][d-1]+1); return s; } void dfs(int s) { int i,j; int b=0,c=0,d=0,e=0; for (i=3;i<=16;i++) { if (a[i]==4) b++; else if (a[i]==3) c++; else if (a[i]==2) d++; else if (a[i]==1) e++; } ans=min(ans,f[b][c][d][e]+s); for (i=3;i<=16;i++) { j=0; while
(i+j<=14&&a[i+j]>=1)//單順子 { if (j>=4) { for (int k=i;k<=i+j;k++) a[k]--; dfs(s+1); for (int k=i;k<=i+j;k++) a[k]++; } j++; } j=0; while (i+j<=14&&a[i+j]>=2)//雙順子 { if (j>=2) { for (int k=i;k<=i+j;k++) a[k]-=2; dfs(s+1); for (int k=i;k<=i+j;k++) a[k]+=2; } j++; } j=0; while (i+j<=14&&a[i+j]>=3)//三順子 { if (j>=2) { for (int k=i;k<=i+j;k++) a[k]-=3; dfs(s+1); for (int k=i;k<=i+j;k++) a[k]+=3; } j++; } } } int main() { freopen("landlords.in","r",stdin); freopen("landlords.out","w",stdout); int t,n,i,j,k,l; scanf("%d%d",&t,&n); for (i=0;i<=17;i++) for (j=0;j<=17;j++) for (k=0;k<=17;k++) for (l=0;l<=17;l++) f[i][j][k][l]=biao(i,j,k,l); while (t-->0) { memset(a,0,sizeof(a)); for (i=1;i<=n;i++) { scanf("%d%d",&j,&k); if (j>2) a[j]++; else if (j>0) a[j+13]++; else a[16]++; } ans=1e9; dfs(0); printf("%d\n",ans); } return 0; }