题目链接:HERE
由于N≤10,可以暴力求出所有取出名字的可能情况,其中符合要求的取出个数最多的便是所求答案。有一个显而易见的剪枝就是当前取出的名字长度之和大于God手中的Long String 的长度时,该分枝便不可能符合要求,直接结束即可。
AC Code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 const long M=110000; 5 char s[M]; 6 long letter[30],name[20][30],vis[30],t,n,ans,s_len; 7 long len[20]; 8 void judge(long now){ 9 long sum; 10 for (long i=0;i<26;++i){ 11 sum=0; 12 for (long j=1;j<=n;++j){ 13 if (!vis[j]) continue; 14 sum+=name[j][i]; 15 if (sum>letter[i]) return; 16 } 17 } 18 ans=std::max(now,ans); 19 } 20 21 void dfs(long x,long now,long now_len){ 22 if (x>n){ judge(now); return;} 23 if (now_len+len[x]<=s_len){ 24 vis[x]=1; dfs(x+1,now+1,now_len+len[x]); 25 } 26 vis[x]=0; dfs(x+1,now,now_len); 27 } 28 29 int main(){ 30 scanf("%d",&t); 31 for (long k=1;k<=t;++k){ 32 getchar(); 33 scanf("%s",s); 34 s_len=strlen(s); 35 memset(letter,0,sizeof(letter)); 36 memset(name,0,sizeof(name)); 37 for (long i=0;i<strlen(s);++i) 38 letter[s[i]-'a']++; 39 scanf("%d",&n); 40 for (long i=1;i<=n;++i){ 41 getchar(); 42 scanf("%s",s); 43 len[i]=strlen(s); 44 for (long j=0;j<strlen(s);++j) 45 name[i][s[j]-'a']++; 46 } 47 48 memset(vis,0,sizeof(vis)); 49 ans=0; 50 dfs(1,0,0); 51 printf("Case #%d: %d ",k,ans); 52 } 53 return 0; 54 }