贪心+dfs
#include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #define INF 1061109567 #define Re register using namespace std; int t,n,f[25][25][25][25][5],cnt[5],card[25],num,ans; inline int dfs2(int on,int tw,int th,int fl,int w){ if(f[on][tw][th][fl][w]<INF){ return f[on][tw][th][fl][w]; } f[on][tw][th][fl][w]=on+tw+th+fl+w; int &now=f[on][tw][th][fl][w]; if(w==2) now=min(now,dfs2(on,tw,th,fl,0)+1); if(fl){ if(tw>=2) now=min(now,dfs2(on,tw-2,th,fl-1,w)+1); if(tw) now=min(now,dfs2(on,tw-1,th,fl-1,w)+1); if(w==2) now=min(now,dfs2(on,tw,th,fl-1,0)+1); if(w&&on) now=min(now,dfs2(on-1,tw,th,fl-1,w-1)+1); if(on>=2) now=min(now,dfs2(on-2,tw,th,fl-1,w)+1); now=min(now,dfs2(on+1,tw,th+1,fl-1,w)); now=min(now,dfs2(on,tw+2,th,fl-1,w)); now=min(now,dfs2(on+2,tw+1,th,fl-1,w)); } if(th){ if(tw) now=min(now,dfs2(on,tw-1,th-1,fl,w)+1); if(w) now=min(now,dfs2(on,tw,th-1,fl,w-1)+1); if(on) now=min(now,dfs2(on-1,tw,th-1,fl,w)+1); now=min(now,dfs2(on+1,tw+1,th-1,fl,w)); now=min(now,dfs2(on+3,tw,th-1,fl,w)); } return f[on][tw][th][fl][w]; } inline int get(){ memset(cnt,0,sizeof(cnt)); for(Re int i=1;i<=13;i++) cnt[card[i]]++; return dfs2(cnt[1],cnt[2],cnt[3],cnt[4],card[14]); } inline void dfs1(int step){ ans=min(ans,step+get()); bool flag; for(Re int i=1;i<=11;i++){ for(Re int j=2;j<=12;j++){ if(i+j-1>12) break; flag=true; for(Re int k=0;k<=j-1;k++){ if(card[i+k]<3) flag=false; } if(!flag) break; for(Re int k=0;k<=j-1;k++) card[i+k]-=3; dfs1(step+1); for(Re int k=0;k<=j-1;k++) card[i+k]+=3; } } for(Re int i=1;i<=10;i++){ for(Re int j=3;j<=12;j++){ if(i+j-1>12) break; flag=true; for(Re int k=0;k<=j-1;k++){ if(card[i+k]<2) flag=false; } if(!flag) break; for(Re int k=0;k<=j-1;k++) card[i+k]-=2; dfs1(step+1); for(Re int k=0;k<=j-1;k++) card[i+k]+=2; } } for(Re int i=1;i<=8;i++){ for(Re int j=5;j<=12;j++){ if(i+j-1>12) break; flag=true; for(Re int k=0;k<=j-1;k++){ if(!card[i+k]) flag=false; } if(!flag) break; for(Re int k=0;k<=j-1;k++) card[i+k]-=1; dfs1(step+1); for(Re int k=0;k<=j-1;k++) card[i+k]+=1; } } } inline void solve(){ memset(card,0,sizeof(card)); for(int i=1;i<=n;i++){ int type,col; cin>>type>>col; if(type==0) type=14; else if(type==1||type==2) type+=11; else if(type>=3&&type<=13) type-=2; card[type]++; } num=0,ans=n; dfs1(0); cout<<ans<<endl; } int main(){ ios::sync_with_stdio(false); memset(f,63,sizeof(f)); cin>>t>>n; for(int i=1;i<=t;i++) solve(); return 0; }
原文:https://www.cnblogs.com/ainiyuling/p/11458557.html