• [NOIPlus]斗地主


    毫无意义的一道题。
    用pai[i]表示某种点数的牌的剩余量,used[i]表示单,对,三,四的出牌数,大力分类讨论,大力dfs即可。。。真奇葩。。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int T,n,ans,pai[20],used[6];
    void dfs(int kth,int v) {
    	if(kth>14) {
    		int nxt=v,a=used[1],b=used[2],c=used[3],d=used[4];
    		if(d>=(a>>1)) nxt-=a-(a&1),d-=a>>1,a&=1;
    		else nxt-=d<<1,a-=d<<1,d=0;
    		if(d>=(b>>1)) nxt-=b-(b&1),d-=b>>1,b&=1;
    		else nxt-=d<<1,b-=d<<1,d=0;
    		if(d>=b) nxt-=b,d-=b,b=0;
    		if(c>=a) nxt-=a,c-=a,a=0;
    		else nxt-=c,a-=c,c=0;
    		if(c>=b) nxt-=b,c-=b,b=0;
    		else nxt-=c,b-=c,c=0;
    		ans=min(ans,nxt);return;
    	}
    	if(!pai[kth]) {dfs(kth+1,v);return;}
    	int now=-1;
    	if(kth>=3) {
    		for(int i=kth;i<=14;i++) {
    			if(pai[i]<3) break;
    			now=i;pai[i]-=3;
    			if(i-kth+1>=2) dfs(kth,v+1);
    		}
    		for(int i=kth;i<=now;i++) pai[i]+=3;
    		now=-1;
    		for(int i=kth;i<=14;i++) {
    			if(pai[i]<2) break;
    			now=i;pai[i]-=2;
    			if(i-kth+1>=3) dfs(kth,v+1);
    		}
    		for(int i=kth;i<=now;i++) pai[i]+=2;
    		now=-1;
    		for(int i=kth;i<=14;i++) {
    			if(!pai[i]) break;
    			now=i;
    			pai[i]--;
    			if(i-kth+1>=5) dfs(kth,v+1);
    		}
    		for(int i=kth;i<=now;i++) pai[i]++;
    	}
    	if(pai[kth]==4) {
    		pai[kth]-=4;
    		used[4]++;dfs(kth+1,v+1);used[4]--;
    		used[3]++,used[1]++,dfs(kth+1,v+2);used[3]--,used[1]--;
    		used[2]+=2;dfs(kth+1,v+2);used[2]-=2;
    		pai[kth]+=4;
    	}
    	else if(pai[kth]==3) {
    		pai[kth]-=3;
    		used[3]++;dfs(kth+1,v+1);used[3]--;
    		used[2]++,used[1]++,dfs(kth+1,v+2),used[2]--,used[1]--;
    		pai[kth]+=3;
    	}
    	else if(pai[kth]==2) {pai[kth]-=2;used[2]++;dfs(kth+1,v+1);used[2]--;pai[kth]+=2;}
    	else if(pai[kth]==1) {pai[kth]--;used[1]++;dfs(kth+1,v+1);used[1]--;pai[kth]++;}
    }
    int main() {
    	scanf("%d%d",&T,&n);
    	while(T--) {
    		ans=9999999;
    		memset(pai,0,sizeof pai);memset(used,0,sizeof used);
    		for(int i=1,a,b;i<=n;i++) {scanf("%d%d",&a,&b);if(a==0) pai[b-1]++;else if(a==1) pai[14]++;else pai[a]++;}
    		if(pai[0]&&pai[1]) pai[0]--,pai[1]--,dfs(2,1),pai[0]++,pai[1]++,dfs(0,0);
    		else dfs(0,0);
    		printf("%d
    ",ans);
    	}
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    一个有趣的js现象
    根相对路径的简单例子
    几道简单有趣的js题(一)
    js流程控制题——如何实现一个LazyMan
    HTML5 十大新特性(十)——Web Socket
    HTML5 十大新特性(九)——Web Storage
    HTML5 十大新特性(八)——Web Worker
    HTML5 十大新特性(七)——拖放API
    HTML5 十大新特性(六)——地理定位
    HTML5 十大新特性(五)——SVG绘图
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9379762.html
Copyright © 2020-2023  润新知