题目链接
题目大意:
给定N个基因片段,每个片段的长度在1到20之间,注意:每个片段长度不一样啊,我一开始以为都为N!求去除重叠基因后字符串的总长最小值
解题思路:
全排列问题啊!将所有的基因片段全排列,两两计算重复的字母个数(模拟即可),最后计算出去除重复基因总长,选择最小值。
典型的DFS问题,但是就因为计算两个基因片段的重复字母数,整整搞了一天!现在看来还是自己太水了!要努力啊
#include <iostream>
using namespace std;
int visit[11];
int genLen[11];
int Min = 0x7fffffff;
int len;
char gen[11][21];
int N;
int size;
int Check(int pre, int cur, int prelen)
{
int i, j, k, len, flag;
if(pre == -1)
return genLen[cur];
for(i = 0; i < genLen[pre]; i++)
{
flag = 1; // 标记是否找到相交的
for(k = i, j = 0; k < genLen[pre]; j++, k++)
{
if(gen[cur][j] != gen[pre][k])
{
flag = 0;
break;
}
}
if(flag)
{
len = prelen + genLen[cur] - (genLen[pre] - i);
return len;
}
}
return (prelen + genLen[cur]);
}
void dfs(int x, int len, int pre)
{
int i, tmp;
if(len > Min) return;
if(x == N)
{
if(len < Min)
Min = len;
return;
}
for(i = 0; i < N; i++)
{
if(visit[i] == 0)
{
tmp = Check(pre, i, len); // 加上第i个字符以后的长度
visit[i] = 1;
dfs((x + 1), tmp ,i);
visit[i] = 0;
}
}
}
int main()
{
int i, j, T;
//freopen("input.txt", "r", stdin);
cin >> T;
while(T--)
{
cin >> N;
for(i = 0; i < N; i++)
{
scanf("%s", gen[i]);
visit[i] = 0;
j = 0;
while(gen[i][j] != '\0')
{
j++;
}
genLen[i] = j;
}
Min = 200;
dfs(0, 0, -1);
cout << Min << endl;
}
return 0;
}