Description
Io和Ao在玩一个单词游戏。他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须 与前一个单词的最后一个字母一致。游戏可以从任何一个单词开始。 任何单词禁止说两遍,游戏中只能使用给定词典中含有的单词。 游戏的复杂度定义为游戏中所使用的单词的长度总和。 编写程序求出使用一本给定的词典来玩这个游戏所能达到的游戏最大可能复杂度。
数据规模限制:单词总数不超过16,单词长度不超过100。
Input
第一行给数字N,代表有多少个单词
下面N行,每行一个单词
Output
最大可能复杂度
Sample Input
3
AE
A
IA
Sample Output
5
HINT
题解
这道题…状态压缩DP裸题啊…
跟之前写过的一道题很像(codevs 2596 售货员的难题,题解传送门)
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct word
{
char first,last;
int length;
};
word a[100];
int f[17][70000];
int n,i,j,k,ans;
char s[109];
int main()
{
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%s",s+1);
a[i].length=strlen(s+1);
a[i].first=s[1];
a[i].last=s[a[i].length];
}
for (i=0;i<=(1<<n)-1;i++)
{
for (j=1;j<=n;j++)
{
if ((i&(1<<(j-1)))!=0)
{
for (k=1;k<=n;k++)
{
if (j!=k)
{
if (i&(1<<(k-1)))
{
if (a[k].last==a[j].first)
{
f[j][i]=max(f[j][i],f[k][i-(1<<(j-1))]+a[k].length);//注意一下状态转移方程
if (f[j][i]>ans)
{
ans=f[j][i];//这里其实不需要的,直接将ans赋值成inf就好了
}
}
}
}
}
}
}
}
for (i=1;i<=n;i++)
{
ans=max(ans,f[i][(1<<n)-1]+a[i].length);
}
printf("%d\n",ans);
return 0;
}