当前位置:软件学习 > Word >>

poj 2817 wordstack

数据规模很小,不免让人想到搜索。但10!=3628800还是不够优秀。

考虑到每次选择只与前一次选择有关,且N<=10,可以通过状态压缩的dp求解。

注意理解题意,允许两个单词中位置相同的字母不同,只是要求位置相同的字母相同的数目最大即可。

可以在dp前做一些预处理。

【代码】


[cpp] 
#include <iostream> 
#include <cstring> 
#include <string> 
#include <cstdio> 
#include <algorithm> 
using namespace std; 
 
int f[2][10][1<<10],g[12][12],len[10][10]; 
string s[10]; 
 
int main() 

    int i,j,k,m,n,x,la,lb,p,ans,tmp; 
 
    freopen("in","r",stdin); 
    while (1) 
    { 
        scanf("%d",&n); 
        if (n<=0) break; 
        memset(len,0,sizeof(len)); 
        for (i=0;i<n;i++) 
            cin >> s[i]; 
        for (i=0;i<n;i++) 
            for (j=0;j<n;j++) 
            if (i!=j) 
            { 
                la=s[i].size(); 
                lb=s[j].size(); 
                memset(g,0,sizeof(g)); 
                for (k=0;k<la;k++) 
                    for (p=0;p<lb;p++) 
                    { 
                        tmp=0; 
                        for (x=0;k+x<la && p+x<lb;x++) 
                            if (s[i][k+x]==s[j][p+x]) tmp++; 
                        len[i][j]=max(len[i][j],tmp); 
                    } 
 
            } 
        m=1<<n; 
        x=0; 
        memset(f[x],255,sizeof(f[x])); 
        for (i=0;i<n;i++) 
            f[x][i][1<<i]=0; 
        for (p=1;p<n;p++) 
        { 
            x^=1; 
            memset(f[x],255,sizeof(f[x])); 
            for (i=0;i<n;i++) 
                for (j=0;j<m;j++) 
                if (f[x^1][i][j]>=0) 
                    for (k=0;k<n;k++) 
                    if (((j>>k)&1)==0) 
                        f[x][k][j|(1<<k)]=max(f[x][k][j|(1<<k)],f[x^1][i][j]+len[i][k]); 
        } 
        ans=0; 
        for (i=0;i<n;i++) 
            ans=max(ans,f[x][i][m-1]); 
        printf("%d\n",ans); 
    } 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,