• 【uoj147】NOIP2015—斗地主


    http://uoj.ac/problem/147 (题目链接)

    题意

      打牌。。。

    Solution

      其实很简单的搜索,当年还是太年轻了。稍微想一想,顺子肯定是要先打掉的,因为顺子所包含的牌最多,所以我们可以以打出了多少张顺子为状态进行搜索,每一种状态,贪心去计算一下对于当前状态还需要打多少次才能将牌打完,不断更新答案即可。

    代码

    // uoj147
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define MOD 1000000007
    #define inf 2147483640
    #define LL long long
    #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=30;
    int c[5],a[maxn],n,T,ans;
    
    int cal() {
    	memset(c,0,sizeof(c));
    	for (int i=0;i<=13;i++) c[a[i]]++;
    	int tot=0;
    	while (c[4] && c[2]>1) c[4]--,c[2]-=2,tot++;
    	while (c[4] && c[1]>1) c[4]--,c[1]-=2,tot++;
    	while (c[4] && c[2]) c[4]--,c[2]--,tot++;
    	while (c[3] && c[2]) c[3]--,c[2]--,tot++;
    	while (c[3] && c[1]) c[3]--,c[1]--,tot++;
    	return tot+c[1]+c[2]+c[3]+c[4];
    }
    void dfs(int x) {
    	if (x>=ans) return;
    	int tmp=cal();
    	ans=min(ans,tmp+x);
    	for (int i=2;i<=13;i++) {
    		int j=i;
    		while (a[j]>=3) j++;
    		if (j-i>=2) {
    			for (int k=i+1;k<=j-1;k++) {
    				for (int l=i;l<=k;l++) a[l]-=3;
    				dfs(x+1);
    				for (int l=i;l<=k;l++) a[l]+=3;
    			}
    		}
    	}
    	for (int i=2;i<=13;i++) {
    		int j=i;
    		while (a[j]>=2) j++;
    		if (j-i>=3) {
    			for (int k=i+2;k<=j-1;k++) {
    				for (int l=i;l<=k;l++) a[l]-=2;
    				dfs(x+1);
    				for (int l=i;l<=k;l++) a[l]+=2;
    			}
    		}
    	}
    	for (int i=2;i<=13;i++) {
    		int j=i;
    		while (a[j]>=1) j++;
    		if (j-i>=5) {
    			for (int k=i+4;k<=j-1;k++) {
    				for (int l=i;l<=k;l++) a[l]--;
    				dfs(x+1);
    				for (int l=i;l<=k;l++) a[l]++;
    			}
    		}
    	}
    }
    int main() {
    	int T;scanf("%d%d",&T,&n);
    	while (T--) {
    		memset(a,0,sizeof(a));
    		for (int x,y,i=1;i<=n;i++) {
    			scanf("%d%d",&x,&y);
    			if (x==1) x=13;
    			else if (x) x--;
    			a[x]++;
    		}
    		ans=n;
    		dfs(0);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Sql Sugar
    GoLang 环境部署
    Typora 自动添加序号
    C# 操作 Oracle批量执行Insert Blob
    C# 生成读取二维码
    Asp.net core 使用Serilog记录日志
    Asp.net Core 将日志输出到文件
    云原生领域的一些技术展望
    C# BeginInvoke用法记录
    C# 委托及线程
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5916311.html
Copyright © 2020-2023  润新知