[noip2015]斗地主(dfs+贪心)

题目:

我是超链接

题解:

一开始就照着大暴力的方向去写,然后华丽丽的T了,只有45pts
然后幡然醒悟:这不是一个普通的暴力!这是一个贪心!
先不考虑顺子的情况,贪心算出连带和单出的情况,按照出的牌从多到少来贪心

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int to[20]={0, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};//大小序 
int m,n,p[20],c[20],ans;
int calc() 
{
    int res=0;
    memset(c,0,sizeof(c));
    for (int i = 0; i <= 13; ++i) ++c[p[i]];
    while (c[4]>0 && c[2]>1) c[4]-=1,c[2]-=2,++res;
    while (c[4]>0 && c[1]>1) c[4]-=1,c[1]-=2,++res;
    while (c[4]>2) c[4]-=2,++res;
    while (c[4]>0 && c[2]>0) c[4]-=1,c[2]-=1,++res;
    while (c[3]>0 && c[2]>0) c[3]-=1,c[2]-=1,++res;
    while (c[3]>0 && c[1]>0) c[3]-=1,c[1]-=1,++res;
    return res + c[1] + c[2] + c[3] + c[4];
}
void ss(int s)
{
    int pos,tot;
    if (s>=ans) return;
    ans=min(ans,s+calc());//不带顺子贪心考虑
    for (int i=2;i<=13;i++)//3-A 
      for (int j=1;j<=3;j++)//1-3顺 
        if (p[i]>=j)//能成为开始 
        {
            tot=0;
            for (pos=i;p[pos]>=j;pos++) p[pos]-=j,tot+=j; 
            for (;--pos>=i;p[pos]+=j,tot-=j)//可以发现不管是什么顺子,至少是5张牌 
              if (tot>=5) ss(s+1);
        }
}
int main() 
{
    int T,n;
    scanf("%d%d",&T,&n);
    while (T--) 
    {
        int x,y;
        memset(p,0,sizeof(p));
        for (int i=1;i<=n;i++)
          scanf("%d%d",&x,&y),++p[to[x]];
        ans=100;ss(0);
        printf("%d\n", ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值