D

题目链接: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 }
原文地址:https://www.cnblogs.com/scnuacm/p/3226709.html