NOIP2015斗地主

乍一看,一脸茫然,没有前途
仔细一看,花色没用,有点前途?

在没有顺子的情况下还是可以乱搞不至于爆0
那么怎么乱搞呢?
核心当然是一次能多出就多出
能出4带两对就出4带两对,然后能出4带2就出4带2;
如果在出完所有的”4带“后对和单还有剩余我们就来出“3带”
同理,先出3带2再出3带1
如果还剩单和对那必是要单出的,所以直接加进步数就可以了
注意:无论是几带2都不可以带出去两个鬼,所以我们把鬼处理到单里面,
但是2个鬼是可以一起出的所以如果我们在最后剩的单大于等于2张而我们又恰好有两张鬼那么我们就可以在我们所得的次数-1=w=
然后我们可以发现(其实是题解君发现=。=)
在没有顺子或者顺子确定的情况下,我们的出牌次数是一定的
那么我们只需要dfs枚举顺子然后在该情况下用上述乱搞就可以了
对于我们找到的顺子,我们可以全出(可能需要拆牌)也可以选择出部分满足条件的顺子,多方案取优
注意对顺子的判定(QAQ卡好久)
注意多组数据的初始化(QAQ卡好久)

const l:array[1..3] of longint=(5,3,3); var tt,n,x,ans:longint; i:longint; a:array[0..25] of longint; num:array[0..15] of longint; cnt:array[0..5] of longint; //几个单、几个对、几个三个、几个四个 function min(a,b:longint):longint; begin if a>1); dec(cnt[4],tt); dec(cnt[2],tt <<1); tt:=min(cnt[4],cnt[1] >> 1); dec(cnt[4],tt); dec(cnt[1],tt <<1); if (cnt[1]<>0) or (cnt[2]<>0) then begin //3 with tt:=min(cnt[3],cnt[2]); dec(cnt[3],tt); dec(cnt[2],tt); tt:=min(cnt[3],cnt[1]); dec(cnt[3],tt); dec(cnt[1],tt); end; //1 2 inc(t,cnt[1]+cnt[2]); if (cnt[1]>=2) and (num[0]=2) then dec(t); //double joker exit(t); end; procedure find(w,len:longint); var i,j:longint; head:longint; begin if (len<1) then exit; ans:=min(ans,w+play); find(w,len-1); head:=-1; for i:=3 to 14 do if (num[i]>=len) then begin if (head=-1) then head:=i else if (i>=head+l[len]-1) then begin for j:=head to i do dec(num[j],len); for j:=head to i do begin if (i>=j+l[len]-1) then find(w+1,len); inc(num[j],len); end; end; end else head:=-1; end; begin read(tt,n); while (tt>0) do begin dec(tt); fillchar(a,sizeof(a),0); fillchar(num,sizeof(num),0); ans:=maxlongint; for i:=1 to n do begin read(a[i],x); if (a[i]=1) then a[i]:=14; inc(num[a[i]]); end; // find(0,3); writeln(ans); end; end.



——by Eirlys
转载请注明出处=w=
【NOIP2015斗地主】NOIP2015斗地主
文章图片


    推荐阅读