洛谷P2668 斗地主 贪心+搜索

来源:互联网 发布:网络推广经典案例 编辑:程序博客网 时间:2024/05/17 22:47

题目连接
https://www.luogu.org/problem/show?pid=2668
只要出去顺子后,剩下的牌出的最优顺序是固定的,可以用贪心从四带2对,四带2张,三带1对,三带1张,剩下的对子和单张依次打出去,再特判一下王炸算一次出去就可以了。
然后就是对顺子进行搜索,单顺子,双顺子,三顺子一次搜索与回溯。
在搜索顺子过程中可以剪枝,如果当前出牌次数大于了ans,就不往下搜索了

 #include<iostream>#include<cstdio>#include<cstring>using namespace std;int t,n,ans,a,b;int card[20],cnt[20];void dfs(int x){    if (x>ans) return ;    memset(cnt,0,sizeof(cnt));    int rest=0;    for (int i=0;i<=14;i++)    cnt[card[i]]++;    while(cnt[4]){        cnt[4]--;        rest++;        if (cnt[2]>=2)        cnt[2]-=2;        else if (cnt[1]>=2)        cnt[1]-=2;    }    while(cnt[3]){        cnt[3]--;        rest++;        if (cnt[2])        cnt[2]--;        else if (cnt[1])        cnt[1]--;    }    if (card[0]&&card[1]&&cnt[1]>=2) rest--;    rest+=cnt[1]+cnt[2];    ans=min(ans,rest+x);    for (int i=3;i<=15;i++){      int j;      for ( j=i;card[j]&&j<=14;j++)         {            card[j]--;            if (j-i+1>=5)            dfs(x+1);         }        while(j>i) card[--j]++;    }    for (int i=3;i<=15;i++){        int j;        for (j=i;card[j]>=2&&j<=14;j++)        {            card[j]-=2;            if (j-i+1>=3)            dfs(x+1);        }        while(j>i) card[--j]+=2;    }    for (int i=3;i<=15;i++){        int j;       for ( j=i;card[j]>=3&&j<=14;j++)        {            card[j]-=3;            if (j-i+1>=2)            dfs(x+1);        }        while(j>i) card[--j]+=3;    }}int main(){    cin>>t>>n;    while(t--){        memset(card,0,sizeof(card));        ans=n;        for (int i=1;i<=n;i++)        {        cin>>a>>b;        if (a==0)        card[b-1]++;        else if (a==1) card[14]++;        else card[a]++;        }        dfs(0);        cout<<ans<<endl;    }    return 0;}   
原创粉丝点击