神奇的题目。。
一开始我准备打暴力直接搜答案。
然后发现。。
无限TLE。。
因为O((logN)^14*T)BOOM。。
然后Zxyer告诉可以只DFS顺子。。。其他的可以一步搞出来。。
然后就0ms了!
Orz zxyer
下面贴代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define inf 0x7fffffff using namespace std; int pai[16]; int s[5]; int ans=inf,n,t,x; int cal(){ s[1]=s[2]=s[3]=s[4]=0; int ans1=0; for (register int i=1;i<=15;i++)s[pai[i]]++; if(pai[14]&&pai[15])ans1++,s[1]-=2; while(s[4]&&s[1]>1)ans1++,s[4]--,s[1]-=2; while(s[4]&&s[2]>1)ans1++,s[4]--,s[2]-=2; while(s[3]&&s[2])ans1++,s[3]--,s[2]--; while(s[3]&&s[1])ans1++,s[3]--,s[1]--; return ans1+s[4]+s[3]+s[2]+s[1]; } void dfs(int q){ if(q>=ans)return; ans=min(ans,q+cal()); register int j; for(register int i=1;i<=11;i++) { j=i; while((j<13)&&(pai[j]>=3)){pai[j++]-=3; if(j-i>1)dfs(q+1);} while(j-i)pai[--j]+=3; } for(register int i=1;i<=10;i++) { j=i; while((j<13)&&(pai[j]>=2)){pai[j++]-=2; if(j-i>2)dfs(q+1); } while(j-i)pai[--j]+=2; } for(register int i=1;i<=8;i++) { j=i; while((j<13)&&(pai[j])){--pai[j++]; if(j-i>4)dfs(q+1);} while(j-i)++pai[--j]; } } int getnum(int q){ int y; scanf("%d",&y); if(!x)return y+13; if(x<3)return x+11; return x-2; } int main(){ scanf("%d",&t);scanf("%d",&n); for(int i=1;i<=t;i++) { memset(pai,0,sizeof(pai)); ans=inf; for(int i=1;i<=n;i++) { scanf("%d",&x); pai[getnum(x)]++; } dfs(0); printf("%d ",ans); } return 0; }