hdu 1560 序列公共组合问题
若从各序列出发不易找到主动的组合方法
所以可以从结论序列的长度和各位置身份出发深搜(每个都尝试)单线路尝试找到最短即出(反向考虑)
IDA* 深度为目标序列长度 最佳覆盖为估值函数
#include<bits/stdc++.h>
using namespace std;
struct one {
string s;
int len;
int now;
}a[10];
int n;
int depth;
string c="ACGT";
int get()
{
int max11=0;
for(int i=1;i<=n;++i)
{
max11=max(max11,a[i].len-a[i].now);
}
return max11;
}//判断:所有都覆盖到最后了,即最长未覆盖序列部分长度为0
bool dfs(int step)//判能否存成功
{
if(!get())
return 1;//判断此路是否成功
if(get()>(depth-step))
return 0;//估值函数
int temp[10];
for(int i=1;i<=n;++i)
{
temp[i]=a[i].now;
}//退回使用
for(int i=0;i<4;++i)
{
bool flag=0;
for(int j=1;j<=n;++j)
{
if(a[j].s[a[j].now]==c[i])
a[j].now++,flag=1;
}//单步变化,即选出当前后对所有的影响
if(flag)//当前有效判断 否则下个循环
{
if(dfs(step+1))
return 1;//深度搜索 成则结束 否则慢慢退回循环(只一条路存在)
for(int k=1;k<=n;++k)
{
a[k].now=temp[k];
}
}
}
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i].s;
a[i].len=a[i].s.length();
a[i].now=0;
}
depth=get();
while(1)
{
if(dfs(0))
break;
depth++;
}
cout<<depth<<endl;
}
return 0;
}