UOJ 147 & 151 [NOIP2015]斗地主

来源:互联网 发布:eureka服务注册源码 编辑:程序博客网 时间:2024/06/04 23:55

暴搜DFS

当初在NOIP2015考场上的时候还是too young,这题只拿了15分,那时候什么都不懂……

考虑到如果不出任何顺子,那么我们可以贪心地出牌,肯定能得到最优解。于是我们在DFS爆搜的时候只要考虑顺子就好了。这样确实可以A掉UOJ147(因为数据比较弱?)然而UOJ151是数据加强(果然好强…),交上去就跪了。原因是有一些点是类似于把两个炸弹拆成四带二来打之类的……加了好多特判才A……

下面是151的代码,在判火箭的地方改一下应该就是147的代码了吧……

#include<cstdio>#include<cstring>#include<algorithm>#define N 16using namespace std;int n, a[N], ans, cnt[5];int calc(){    int ret=0, temp;    memset(cnt,0,sizeof(cnt));    for(int i = 0; i <= 14; i++)        cnt[a[i]]++;    if(cnt[4])    {        temp=min(cnt[4],cnt[2]/2);        ret+=temp;        cnt[4]-=temp;        cnt[2]-=2*temp;        temp=min(cnt[4],cnt[1]/2);        ret+=temp;        cnt[4]-=temp;        cnt[1]-=2*temp;    }    if(cnt[3])    {        temp=min(cnt[3],cnt[2]);        ret+=temp;        cnt[3]-=temp;        cnt[2]-=temp;        temp=min(cnt[3],cnt[1]);        ret+=temp;        cnt[3]-=temp;        cnt[1]-=temp;    }    for(int i = 1; i <= 4; i++)        ret+=cnt[i];    if(cnt[1]>=2 && a[0] && a[1])        ret--;//火箭    return ret;}void dfs(int step){    if(step>=ans)return;    ans=min(ans,step+calc());    for(int i = 3; i <= 14; i++)        if(a[i]>=3)            for(int j = i+1; j <= 14; j++)            {                if(a[j]<3)break;                for(int k = i; k <= j; k++)a[k]-=3;                dfs(step+1);                for(int k = i; k <= j; k++)a[k]+=3;            }    for(int i = 3; i <= 14; i++)        if(a[i]>=2)            for(int j = i+1; j <= 14; j++)            {                if(a[j]<2)break;                if(j-i<2)continue;                for(int k = i; k <= j; k++)a[k]-=2;                dfs(step+1);                for(int k = i; k <= j; k++)a[k]+=2;            }    for(int i = 3; i <= 14; i++)        if(a[i]>=1)            for(int j = i+1; j <= 14; j++)            {                if(a[j]<1)break;                if(j-i<4)continue;                for(int k = i; k <= j; k++)a[k]--;                dfs(step+1);                for(int k = i; k <= j; k++)a[k]++;            }    for(int i = 2; i <= 14; i++)    {        if(a[i]==4)        {            for(int j = 2; j <= 14; j++)            {                if(j==i)continue;                if(a[j]==4)                {                                       a[i]=a[j]=0;                    dfs(step+1);                    a[i]=a[j]=4;                }                if(a[j]>=3)                    for(int k = 2; k <= 14; k++)                    {                        if(k==i||k==j)continue;                        if(a[k]>=2)                        {                            a[i]-=4;                            a[j]-=2;                            a[k]-=2;                            dfs(step+1);                            a[i]+=4;                            a[j]+=2;                            a[k]+=2;                        }                    }                if(a[j]>=2)                {                    for(int k = 2; k <= 14; k++)                    {                        if(k==i||k==j)continue;                        if(a[k]>=1)                        {                            a[i]-=4;                            a[j]-=1;                            a[k]-=1;                            dfs(step+1);                            a[i]+=4;                            a[j]+=1;                            a[k]+=1;                        }                    }                    a[i]-=4;                    a[j]-=2;                    dfs(step+1);                    a[i]+=4;                    a[j]+=2;                }            }         }        if(a[i]==3)        {            for(int j = 2; j <= 14; j++)            {                if(j==i)continue;                if(a[j]>=2)                {                    a[i]-=3;                    a[j]-=1;                    dfs(step+1);                    a[i]+=3;                    a[j]+=1;                }                if(a[j]>=3)                {                    a[i]-=3;                    a[j]-=2;                    dfs(step+1);                    a[i]+=3;                    a[j]+=2;                }            }        }    }}int main(){    int T;    scanf("%d%d",&T,&n);    while(T--)    {        memset(a,0,sizeof(a));        for(int i = 1, x, y; i <= n; i++)        {            scanf("%d%d",&x,&y);            if(x==1)x=14;            else if(x==0 && a[0])x=1;            a[x]++;        }        ans=calc();        dfs(0);        printf("%d\n",ans);    }} 
0 0