用动态规划法解决最长公共子序列问题.docx
《用动态规划法解决最长公共子序列问题.docx》由会员分享,可在线阅读,更多相关《用动态规划法解决最长公共子序列问题.docx(7页珍藏版)》请在冰豆网上搜索。
![用动态规划法解决最长公共子序列问题.docx](https://file1.bdocx.com/fileroot1/2023-1/30/278360dd-1538-4e96-8e7f-8f9432973834/278360dd-1538-4e96-8e7f-8f94329738341.gif)
用动态规划法解决最长公共子序列问题
用动态规划法解决最长公共子序列问题
动态规划解最长子序列
一、课程设计目的
掌握动态规划法的原理,并能够按其原理编程实现求两个序列数据的最长公共子系列,以加深对其的理解。
二、课程设计内容
1、用动态规划法解决最长子序列问题
2、交互输入两个序列数据
3、输出两个序列的最长公共子序列
三、概要设计
四、详细设计与实现
#inelude"iostream.h"
#inelude"iomanip.h"
#definemax100
voidLCSLength(intm,intn,char*x,char
*y,char*b)
{
inti,j,k;
intc[max][max];
for(i=1;i<=m;i++)
{
c[i][0]=0;
}
for(i=1;i<=n;i++)
{
c[O][i]=O;
}
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
if(x[i-1]==y[j-1])
{c[i][j]=c[i-1][j-1]+1;k=i*(n+1)+j;
b[k]='\\';
}
elseif(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
k=i*(n+1)+j;b[k]='|';
}else{c[i][j]=c[i][j-1];
k=i*(n+1)+j;b[k]='-';
}
}
}
}
voidLCS(inti,intj,char*x,char*b,intwidth){
if(i==0||j==0)
return;
intk=i*(width+1)+j;
if(b[k]=='W){
LCS(i-1,j-1,x,b,width);cout<}
elseif(b[k]=='|')
{
LCS(i-1,j,x,b,width);
}
else
{
LCS(i,j-1,x,b,width);
}
}
voidmain()
{
charx[max]={'a','b','c','b','d','a','b'};chary[max]={'b','d','c','a','b','a'};intm=7;
intn=6;
charb[max]={0};
LCSLength(m,n,x,y,b);
LCS(m,n,x,b,n);
cout«endl«endl;
最长公共子序列冋题具有最优子结构性质
设
X={x1,...,xm}
Y={y1,…,yn}
及它们的最长子序列
Z={z1,...,zk}
则
1、若xm=yn,贝Vzk=xm=yn,且
Z[k-1]是X[m-1]和丫[n-1]的最长公共子序列
2、若xm!
=yn,
且zk!
=xm,则Z是X[m-1]和丫的最长公共子序列
3、若xm!
=yn,且zk!
=yn,则」Z是Y[n-1]和X的最长公共子序列
由性质导出子问题的递归结构当i=0,j=0时,c[i][j]=0当i,j>0;xi=yi时,c[i][j]=c[i-1][j-1]+1当i,j>0;xi!
=yi时,c[i][j]=max{c[i][j-1],c[i-1][j]}#include
#definemax(a,b)a>b?
a:
b
#defineM100
voiddisplay(int&n,int&C,intw[M],intv[M]){
inti;
cout<<"请输入物品种数n:
";
cin>>n;
cout<coutvv"请输入背包总容量C:
";
cin>>C;
cout«endl;
cout<<"请输入各物品的大小或重量
w:
"<w[0]=0;
for(i=1;i<=n;i++)
cin>>w[i];
cout<<"请输入各物品其价值v:
"<v[0]=0;
for(i=1;i<=n;i++)
cin>>v[i];
};
intknapsack(int&n,int&C,intw[M],int
v[M],intV[M][M])
{
inti,j;
for(i=0;i<=n;i++)
for(j=0;j<=C;j++)
{
if(i==0||j==0)
V[i][j]=0;
elseif(w[i]>j)
V【i][j]=V【i-1][j];
elseif(w[i]<=j)
V【i]【j]=max(V[i-1]【j],V【i-1]【j-w[i]]+v[i]);
}
returnV[n]【C];
};
voidtraceback(intn,intC,intw[M],intx[M],int
V[M][M])
{
for(inti=1;i<=n;i++)
{
if(V[i][C]==V[i-1][C])
x[i]=0;
else
{
x[i]=1;
C=C-w[i];
}
}
〃x[n]=(V[n][C]>0)?
1:
0;
};
voidmain()
{
inti,j,n,C;
charch;
intw[M],v[M],x[M];
intV[M][M];
while⑴
{
display(n,C,w,v);
"<cout<<"运算结果如下:
for(i=1;i<=n;i++)x[i]=0;
knapsack(n,C,w,v,V);cout<<"";for(j=0;j<=C;j++)cout<cout<for(i=0;i<=n;i++)
{
cout<
for(j=0;j<=C;j++)
{cout«V[i][j]vv"";
}
cout«endl;cout«endl;
}
cout<<"选择的物向量表示为
cout«"(";
traceback(n,C,w,x,V);
for(i=1;i<=n;i++)cout<大价值
否则按任意键
cout<<")"<cout<<"背包最为:
"<cout<cout<<"按Y或y继续操作,"<cin>>ch;
if(ch=='Y'||ch=='y')continue;
else
break;