POJ 2817 WordStack

来源:互联网 发布:云计算的未来发展趋势 编辑:程序博客网 时间:2024/05/21 17:59

题目链接:http://poj.org/problem?id=2817


题意:有n个单词,如果两个单词相邻,可以在一个单词前面填充一些空格,使得两个单词对应位置上的字母相同(这些位置可以不相邻),最大的相同数量为这两个单词所产生的值。现在要找到一种排列方式,使得这些单词产生值之和最大。

思路:先计算出这些单词两两相邻所产生的值,在LCS的基础上做了一个小改动。然后用状态压缩DP计算,当前已经选了哪些单词作为状态,这些单词当中的最后一个选的单词是哪个。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007const int maxn = 12;int n;int len[maxn];char str[maxn][15];int a[maxn][maxn];int dp[1<<10][maxn];int cal(int x,int y){    int f[maxn][maxn];    Clean(f,0);    int lenx = len[x];    int leny = len[y];    int ans = 0;    rep(i,0,lenx-1)        rep(j,0,leny-1)        {            if ( str[x][i] == str[y][j] )            {                f[i+1][j+1] = f[i][j] + 1;            }            else f[i+1][j+1] = f[i][j];            ans = max(ans,f[i+1][j+1]);        }    return ans;}bool init(){    scanf("%d",&n);    if ( n < 1 ) return false;    getchar();    rep(i,1,n)    {        gets(str[i]);        len[i] = strlen(str[i]);    }    rep(i,1,n)        rep(j,1,n)        if ( i != j ) a[i][j] = cal(i,j);    Clean(dp,-1);    return true;}int main(){    while(init())    {        int uplim = 1<<n;        rep(i,1,uplim-1)        {            rep(j,1,n)            if ( i & 1<<(j-1) )            {                int last = i & ~(1<<(j-1));                if ( last == 0 )                {                    dp[i][j] = 0;                    break;                }                rep(k,1,n)                if ( ( last & 1<<(k-1) ) && dp[last][k] != -1 )                    dp[i][j] = max( dp[i][j] , dp[last][k] + a[k][j] );            }        }        int ans = 0;        rep(i,1,n) ans = max( ans , dp[uplim-1][i] );        cout<<ans<<endl;    }    return 0;}


0 0