您的位置:首页 > 编程语言 > Go语言

poj2817状态压缩DP

2015-09-26 10:10 465 查看
//输出最大的与前一个字符相同的个数之和
//184K 0MS
//主要要理解是状态压缩DP,状态是是否选择了该字符
//并且保存状态时候因为字符之间有顺序,所有需要保存最后一个字符
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

#define  MAXN  12
static int N;
static char words[MAXN][MAXN];
static int len[MAXN][MAXN];
static int dp[1050][MAXN];//表示是否有该状态以及当前状态下最后一个字符

static int calcNums(int i,int j)
{
int k1,k2;
k1 = k2 = 0;
int len1 = strlen(words[i]);
int len2 = strlen(words[j]);
int ret = -1;
for (k1=0;k1<len2;++k1)
{
int tmp = 0;
int k3;
for (k2=k1,k3=0;k2<len2&&k3<len1;++k2,++k3)
if (words[i][k3]==words[j][k2])tmp++;
if (tmp>ret)
ret = tmp;
}
for (k1=0;k1<len1;++k1)
{
int tmp = 0;
int k3;
for (k2=k1,k3=0;k2<len1&&k3<len2;++k2,++k3)
if (words[i][k2]==words[j][k3])tmp++;
if (tmp>ret)
ret = tmp;
}

return ret;
}

static void init()
{
memset(len,0,sizeof(len));
for (int i=0;i<N;++i)
{
for (int j=i+1;j<N;++j)
{
len[i][j] = len[j][i] = calcNums(i,j);
}
}
}

static void DP()
{
memset(dp,0,sizeof(dp));
for (int s=0;s<(1<<N)-1;++s)
{
for (int i=0;i<N;++i)//选择当前状态的最后一个字符
{
if(s&(1<<i))//如果有该状态
for (int j=0;j<N;++j)
{
if (i!=j&&(s&(1<<j))==0)
{
dp[s|(1<<j)][j] = max(dp[s|(1<<j)][j],dp[s][i]+len[i][j]);
}
}
}
}

int ans = 0;
for (int i=0;i<N;++i)
{
if (dp[(1<<N)-1][i]>ans)
ans = dp[(1<<N)-1][i];
}
printf("%d\n",ans);
}
int main()
{
while(scanf("%d",&N)&&N)
{
for (int i=0;i<N;++i)
scanf("%s",words[i]);
init();
DP();
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm dp 算法 poj 压缩