简单的字符串处理,枚举即可。
比对的条件是使用的字母的集合是给定集合的子集,且价值最大。
考虑到猥琐的输出顺序,我先枚举一次求出max,再枚举一次输出符合条件的串。
具体的顺序处理见我的程序。
第一次在usaco上爆内存。它的英文是resource limits exceeded.恩学会了。
程序中maxm显然不需要取40001   ,极端情况下maxm=7!+6!+5!+4!+3!+2!+1+(3!+2!+1)*(4!+3!+2!+1)=14102。
而实际数据中的m远远小于这个数。(linux 下的calculator好强大,粘贴上面那个算式,立刻出解)

 code
code
/*
USER:zyn19961
TASK:lgame
LANG:C++
*/
#include<cstdio>
#include<cstring>
    int const maxm=14102;
    char t[8];
    int q[maxm][127];
    int qq[127];
    char word[maxm][8];
    int score[maxm];
    int na[127]={2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7};
    int nn[127];
    int m=1;
    int max=0;
    int ans1[maxm];
int ansa[maxm];
    int ansb[maxm];
    int main(){
        freopen("lgame.in","r",stdin);
        freopen("lgame.out","w",stdout);
        memset(qq,0,sizeof(qq));
        memset(q,0,sizeof(q));
        memset(score,0,sizeof(score));
        for(int i=0;i<=25;i++)
            nn['a'+i]=na[i];
        scanf("%s",t);fclose(stdin);
        for(int i=0;i<=strlen(t);i++)
            qq[t[i]]++;
        freopen("lgame.dict","r",stdin);
        for(;;){
            scanf("%s",word[m]);
            if(word[m][0]=='.'){
                m--;
                break;
                }
            memset(q[m],0,sizeof(q[m]));
            for(int i=0;i<=strlen(word[m]);i++)
                q[m][word[m][i]]++;
            bool flag=true;
            for(int i='a';i<='z';i++)
                if(q[m][i]>qq[i]){
                    flag=false;
                    break;
                    }
            if(flag){
                for(int i='a';i<='z';i++)
                    score[m]+=q[m][i]*nn[i];
                m++;
                }
            }
        for(int i=1;i<=m;i++){
            bool flag=true;
            for(int k='a';k<='z';k++)
                if(q[i][k]>qq[k]){
                    flag=false;
                    break;
                    }
            if(score[i]>max&&flag)
                max=score[i];
            for(int j=i+1;j<=m;j++){
                bool flag=true;
                for(int k='a';k<='z';k++)
                    if(q[i][k]+q[j][k]>qq[k]){
                        flag=false;
                        break;
                        }
                if(score[i]+score[j]>max&&flag)
                    max=score[i]+score[j];
                }
            }
        printf("%d\n",max);
        for(int i=1;i<=m;i++){
            bool flag=true;
            for(int k='a';k<='z';k++)
                if(q[i][k]>qq[k]){
                    flag=false;
                    break;
                    }
            if(score[i]==max&&flag)
                printf("%s\n",word[i]);
            for(int j=i+1;j<=m;j++){
                bool flag=true;
                for(int k='a';k<='z';k++)
                    if(q[i][k]+q[j][k]>qq[k]){
                        flag=false;
                        break;
                        }
                if(score[i]+score[j]==max&&flag)
                    printf("%s %s\n",word[i],word[j]);
                }
            }
        fclose(stdin);
        fclose(stdout);
        return 0;
        }