题意:
给你牌,问你最少几次全部打出去QAQ恶心
所以,暴力呗。。然而。。各种TLE
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define olinr return #define _ 0 #define love_nmr 0 #define DB double int T; int n; int t[20]; int ans; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } inline void dfs(int dep) { for(int i=3;i<=17;i++) { if(t[i]) break; if(i==17) { ans=min(ans,dep); return; } } if(t[16]&&t[17]) { t[16]=t[17]=0; dfs(dep+1); } for(int i=3;i<=14;i++) //三顺子 for(int j=i+1;j<=14;j++) { for(int k=i;k<=j;k++) if(t[k]<3) goto wmy; for(int k=i;k<=j;k++) t[k]-=3; dfs(dep+1); for(int k=i;k<=j;k++) t[k]+=3; wmy:; } for(int i=3;i<=14;i++) //双顺子 for(int j=i+2;j<=14;j++) { for(int k=i;k<=j;k++) if(t[k]<2) goto shit; for(int k=i;k<=j;k++) t[k]-=2; dfs(dep+1); for(int k=i;k<=j;k++) t[k]+=2; shit:; } for(int i=3;i<=14;i++) //单顺子 for(int j=i;j<=14;j++) { for(int k=i;k<=j;k++) if(!t[k]) goto girlfriend; for(int k=i;k<=j;k++) t[k]--; dfs(dep+1); for(int k=i;k<=j;k++) t[k]++; girlfriend:; } for(int i=3;i<=15;i++) //四带二 { if(t[i]==4) { t[i]=0; for(int j=3;j<=17;j++) { if(t[j]) { t[j]--; for(int k=j;k<=17;k++) { if(t[k]) { t[k]--; dfs(dep+1); t[k]++; } } t[j]++; } } for(int j=3;j<=17;j++) { if(t[j]>=2) { t[j]-=2; for(int k=j;k<=17;k++) { if(t[k]>=2) { t[k]-=2; dfs(dep+1); t[k]+=2; } } t[j]+=2; } } t[i]=4; } } for(int i=3;i<=15;i++) //三带二 { if(t[i]>=3) { t[i]-=3; for(int j=3;j<=15;j++) { if(t[j]>=2) { t[j]-=2; dfs(dep+1); t[j]+=2; } } t[i]+=3; } } for(int i=3;i<=15;i++) //三带一 { if(t[i]>=3) { t[i]-=3; for(int j=3;j<=15;j++) { if(t[j]) { t[j]--; dfs(dep+1); t[j]++; } } t[i]+=3; } } for(int i=3;i<=15;i++) //三不带 { if(t[i]>=3) { t[i]-=3; dfs(dep+1); t[i]+=3; } } for(int i=3;i<=15;i++) //对子 { if(t[i]>=2) { t[i]-=2; dfs(dep+1); t[i]+=2; } } } inline void init() { ans=n; memset(t,0,sizeof t); for(int i=1;i<=n;i++) { int x=read(); int y=read(); if(x>=3&&x<=13) t[x]++; else if(x==0) { if(y==1) t[16]++; else t[17]++; } else t[13+x]++; } } int main() { T=read(); n=read(); while(T--) { init(); dfs(0); put(ans); putchar(' '); } olinr ~~(0^_^0)+love_nmr; }
对于单的和双的,耗时太多了QAQ
所以后来发现了一个桶套桶的贪心做法
tong[i]代表牌数为i的有几种
贪心QAQ
#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define olinr return #define _ 0 #define love_nmr 0 #define DB double int T; int n; int t[20]; int ans; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } int tong[20]; inline int tanxin() { int tot=0; memset(tong,0,sizeof tong); for(int i=3;i<=16;i++) tong[t[i]]++; while(tong[4]&&tong[2]>=2) { tong[4]--; tong[2]-=2; tot++; } while(tong[4]&&tong[1]>=2) { tong[4]--; tong[1]-=2; tot++; } while(tong[4]&&tong[2]) { tong[4]--; tong[2]--; tot++; } while(tong[3]&&tong[2]) { tong[3]--; tong[2]--; tot++; } while(tong[3]&&tong[1]) { tong[3]--; tong[1]--; tot++; } return tot+tong[1]+tong[2]+tong[3]+tong[4]; } inline void dfs(int dep) { // for(int i=3;i<=17;i++) // { // if(t[i]) break; // if(i==17) // { // ans=min(ans,dep); // return; // } // } if(dep>=ans) return; ans=min(ans,dep+tanxin()); for(int i=3;i<=14;i++) { int maxn=i; while(t[maxn]>=3&&maxn<=14) maxn++; maxn--; for(int j=i+1;j<=maxn;j++) { for(int k=i;k<=j;k++) t[k]-=3; dfs(dep+1); for(int k=i;k<=j;k++) t[k]+=3; } } for(int i=3;i<=14;i++) { int maxn=i; while(t[maxn]>=2&&maxn<=14) maxn++; maxn--; for(int j=i+2;j<=maxn;j++) { for(int k=i;k<=j;k++) t[k]-=2; dfs(dep+1); for(int k=i;k<=j;k++) t[k]+=2; } } for(int i=3;i<=14;i++) { int maxn=i; while(t[maxn]&&maxn<=14) maxn++; maxn--; for(int j=i+4;j<=maxn;j++) { for(int k=i;k<=j;k++) t[k]--; dfs(dep+1); for(int k=i;k<=j;k++) t[k]++; } } } inline void init() { ans=n; memset(t,0,sizeof t); for(int i=1;i<=n;i++) { int x=read(); int y=read(); if(x>=3&&x<=13) t[x]++; else if(x==0) t[16]++; else t[13+x]++; } } int main() { T=read(); n=read(); while(T--) { init(); dfs(0); put(ans); putchar(' '); } olinr ~~(0^_^0)+love_nmr; }
再加了点小优化,时间顿时大大减少(虽然加强版过不了)