斗地主

来源:互联网 发布:淘宝男士运动秋装 编辑:程序博客网 时间:2024/06/10 04:01

2015最后一题,这道题是大爆搜+贪心,先枚举四带一,三带一,单牌,etc,再枚举顺子优化解,在搜索优化的解是不是优化的(不一定是最优的,所以要递归),在递归回去,找别的顺子优化。
在说花色有什么用啊

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int t,n;int s[5]; int a[9999],b[9999];int ans=23;void dfs(int x){    if(ans<x)return ;    memset(s,0,sizeof(s));    for(int i=1;i<=14;i++)     {        if(a[i]==1||a[i]==2)        s[a[i]]++;    }//记录单张和双张    for(int i=2;i<=14;i++)    {        if(a[i]==4)        {            s[4]++;            if(s[1]>=2) s[1]-=2;            else if(s[2]>=2) s[2]-=2;            else if(s[2]>=1) s[2]--;        }       }//打出所有的四带...    for(int i=2;i<=14;i++)    {        if(a[i]==3)        {            s[3]++;            if(s[1]>=1) s[1]--;            else if(s[2]>=1) s[2]--;        }    }//打出所有的三带。。。。    int w=0;    for(int i=1;i<=4;i++)    w+=s[i];//找最优解    ans=min(ans,x+w);    int j;    for(int i=3;i<=10;i++)//找单顺子优化解    {        for( j=i;j<=14;j++)        {            a[j]--;            if(a[j]<0)break;            if(j-i>=4) dfs(x+1);//搜索        }        if(j==15)j--;        while(j>=i)a[j--]++;//回溯    }        for(int i=3;i<=12;i++)//找双顺子优化    {        for( j=i;j<=14;j++)        {            a[j]-=2;            if(a[j]<0) break;            if(j-i>=2) dfs(x+1);        }        if(j==15) j--;        while(i<=j) a[j--]+=2;    }        for(int i=3;i<=13;i++)//找三顺子优化    {        for( j=i;j<=14;j++)        {            a[j]-=3;            if(a[j]<0)break;            if(j-i>=1) dfs(x+1);        }        if(j==15) j--;        while(i<=j) a[j--]+=3;    }    return ;} int main(){    scanf("%d%d",&t,&n);    for(int i=1;i<=t;i++)    {        memset(a,0,sizeof(a));         for(int i=1;i<=n;i++)        {            int x;            scanf("%d%d",&x,&b[i]);            if(x==1)a[14]++;            else if(x==0)a[1]++;            else a[x]++;        }        ans=14;//最大是14        dfs(0);        printf("%d\n",ans);    }}