NOIP2015斗地主

表示本来觉得自己斗地主玩得挺好的也挺喜欢的做了这题之后对于斗地主的看法完全改变了(原来可以这样拆牌?)。
做这题之前就听见别人说暴力搜顺子贪心出散牌,所以就是每一层搜下顺子,再计算一下打出剩下牌的最小次数,其实主要还是模拟。

#include<bits/stdc++.h>
#define il inline
#define ll long long
using namespace std;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il int read(){
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
    return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(ll x){
    if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
int T,n,ans,a[15],cd[15],sz[4]={0,5,3,2};
il int calc(){
    memset(a,0,sizeof(a));
    for(int i=0;i<=13;++i) ++a[cd[i]];
    int tot=0;
    while(a[4]&&a[2]>=2) --a[4],a[2]-=2,++tot;
    while(a[4]&&a[1]>=2) --a[4],a[1]-=2,++tot;
    while(a[4]&&a[2]) --a[4],--a[2],++tot;
    while(a[3]&&a[2]) --a[3],--a[2],++tot;
    while(a[3]&&a[1]) --a[3],--a[1],++tot;
    return tot+a[1]+a[2]+a[3]+a[4];
}
il int shunzi(int i,int x){
    int p=i;
    while(cd[p]>=x&&p<=13) ++p;
    if(p-i>=sz[x]) return p;
    return 0;
}
il void dfs(int s){
    if(s>=ans) return;
    ans=min(ans,s+calc());
    int pos;
    for(int k=3;k;--k)
    for(int i=2;i<=13;++i)
    if(shunzi(i,k)){
        pos=shunzi(i,k);
        for(int j=i+sz[k]-1;j<=pos-1;++j){
            for(int v=i;v<=j;++v) cd[v]-=k;
            dfs(s+1);
            for(int v=i;v<=j;++v) cd[v]+=k;
        }
    }
}
int main(){
    T=read(),n=read();
    while(T--){
        ans=33;
        memset(cd,0,sizeof(cd));
        for(int i=1;i<=n;++i){
            int x=read(),y=read();
            if(x==1) x=13;
            else if(x) --x;
            ++cd[x];
        }
        dfs(0);print(ans);
    }Ot();return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值