算法分析与设计实验二.docx
《算法分析与设计实验二.docx》由会员分享,可在线阅读,更多相关《算法分析与设计实验二.docx(10页珍藏版)》请在冰豆网上搜索。
![算法分析与设计实验二.docx](https://file1.bdocx.com/fileroot1/2023-1/24/5a971528-05ee-43bd-8733-6d0dab1bfc1c/5a971528-05ee-43bd-8733-6d0dab1bfc1c1.gif)
算法分析与设计实验二
实验二、动态规划算法的应用
班级:
计072
学号:
3070911052
姓名:
赵凯
一、实验目的与实验内容
1、掌握动态规划算法的基本设计思想与原则。
2、最长公共子序列、0-1背包,找零钱
二、实验要求
1.用C++/C完成算法设计和程序设计并上机调试通过。
2.撰写实验报告,提供实验结果和数据。
3.分析算法,要求给出具体的算法分析结果,包括时间复杂度和空间复杂度,并简要给出算法设计小结和心得。
三、程序实现
最长公共子序列:
对字符串X和Y,首先构建子问题最有值的递归关系。
用c[i][j]记录序列Xi和Yj的最长公共子序列的长度。
其中Xi={x1,x2,…,xi};Yj={y1,y2,…,yj}.当i=0或j=0时,空序列就是Xi和Yj的最长公共子序列。
故此时c[i][j]=0.其他情况下,由最优子结构性质可建立递归关系如下:
0i=0,j=0
c[i][j]=c[i-1][j-1]+1i,j>0;xi=yj
max{c[i][j-1],c[i-1][j]}i,j>0;xi=yj
0-1背包问题:
设所给0-1背包问题的子问题
max∑nk=ivkxk
∑nk=ivkxk<=j
xk∈{0.1},i<=k<=n
的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。
由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下:
m(i,j)=max{m(i+1,j),m(i+1,j-wi)+vi}j>=wi
m(i+1,j)0<=jvnj>=wn
m(n,j)=00<=j找零钱:
在这次实验中,由于听错实验的最后一个题目,所以找零钱的这个实验我是完全参照0-1背包问题的。
时间复杂度:
最长公共子序列:
计算最优值c[i][j]的算法设计中,双层循环外规模为m,内规模为n,所以计算它的时间复杂度为0(mn).
0-1背包与找零钱:
由他的递归表达式可得时间复杂度为0(nc).
四、心得体会
通过此次实验,我的最深感触就是对算法的思想一定要理解,不然只是徒劳。
刚开始做实验时,我什么也没看,直接拿着题目就凝思苦想,然而没有头绪。
在把课本上的东西看了之后,通过仔细查看动态规划的思想,我明白了如何规划问题,如何解决问题。
关键还是要做到心里有底,然后才能胸有成竹,
五、源程序清单。
最长公共子序列:
#include
usingnamespacestd;
voidLCSLength(intm,intn,charx[],chary[],intc[][8],intb[][8])//求最优值
{
inti,j;
for(i=1;i<=m;i++)c[i][0]=0;
for(i=1;i<=n;i++)c[0][i]=0;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{
if(x[i]==y[j])
{
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
}
elseif(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]=2;
}
else{
c[i][j]=c[i][j-1];
b[i][j]=3;
}
}
}
voidLCS(inti,intj,charx[],intb[][8])//求最优解
{
if(i==0||j==0)return;
if(b[i][j]==1){
LCS(i-1,j-1,x,b);
cout<}
elseif(b[i][j]==2)LCS(i-1,j,x,b);
elseLCS(i,j-1,x,b);
}
intmain()
{
charx[8];
chary[7];
intc[8][8]={0};
intb[8][8]={0};
cout<<"inputstringx"<for(inti=0;i<9;i++)
cin>>x[i];
cout<cout<<"inputstringy"<for(intj=0;j<8;j++)
cin>>y[j];
cout<LCSLength(7,6,x,y,c,b);
cout<<"thebestvalue:
"<for(i=0;i<=7;i++)
{
for(intj=0;j<=6;j++)
cout<cout<}
cout<<"最长公共子序列:
"<LCS(7,6,x,b);
cout<return0;
}
0-1背包问题:
#include
usingnamespacestd;
voidtback(intm[][11],intt[],intc,intn,intx[]);
voidknapsack(intv[],intw[],intc,intn,intm[][11])//最优值的求解过程
{
intjmax=(w[n]-1)>c?
c:
(w[n]-1);
for(intj=0;j<=jmax;j++)
m[n][j]=0;
for(j=w[n];j<=c;j++)
m[n][j]=v[n];
for(inti=n-1;i>=0;i--)
{
jmax=(w[i]-1>c)?
c:
(w[i]-1);
for(j=0;j<=jmax;j++)
m[i][j]=m[i+1][j];
for(j=w[i];j<=c;j++)
m[i][j]=m[i+1][j]>(m[i+1][j-w[i]]+v[i])?
m[i+1][j]:
(m[i+1][j-w[i]]+v[i]);
}
m[1][c]=m[2][c];
if(c>=w[1])
{m[1][c]=m[1][c]>(m[2][c-w[1]]+v[1])?
m[1][c]:
(m[2][c-w[1]]+v[1]);
}
intmain()
{
inti,j,n=5,c,x[6],count=0;
intv[6];
intw[6];
cout<<"inputarryv:
";
for(i=0;i<6;i++)
{x[i]=i;
cin>>v[i];
}
cout<<"arryvis:
"<for(i=0;i<6;i++)
cout<cout<<"inputarryw:
";
for(i=0;i<6;i++)
cin>>w[i];
cout<<"arrywis:
"<for(i=0;i<6;i++)
cout<intm[7][11]={0};
cout<<"inputvolum:
"<cin>>c;
knapsack(v,w,c,n,m);
for(i=1;i<=n;i++)
{
for(j=1;j<=c;j++)
cout<cout<}
tback(m,w,c,n,x);
cout<<"theresultis:
";
for(i=0;i{
if(x[i])
{cout<count++;
}
}
cout<cout<<"latestnumber="<return0;
}
voidtback(intm[][11],intw[],intc,intn,intx[])//最优解得求解过程
{
for(inti=0;i{
if(m[i][c]==m[i+1][c])
x[i]=0;
else
{
x[i]=1;
c-=w[i];
}
x[n]=(m[n][c])?
1:
0;
}
}
找零钱:
#include
usingnamespacestd;
voidtback(intm[][11],intt[],intc,intn,intx[]);
voidknapsack(intv[],intw[],intc,intn,intm[][11])//最优值
{
intu=(w[n]-1)>c?
c:
(w[n]-1);
for(intj=0;j<=u;j++)
m[n][j]=0;
for(j=w[n];j<=c;j++)
m[n][j]=v[n];
for(inti=n-1;i>=0;i--)
{
u=(w[i]-1>c)?
c:
(w[i]-1);
for(j=0;j<=u;j++)
m[i][j]=m[i+1][j];
for(j=w[i];j<=c;j++)
m[i][j]=m[i+1][j]>(m[i+1][j-w[i]]+v[i])?
m[i+1][j]:
(m[i+1][j-w[i]]+v[i]);
}
m[1][c]=m[2][c];
if(c>=w[1])
m[1][c]=m[1][c]>(m[2][c-w[1]]+v[1])?
m[1][c]:
(m[2][c-w[1]]+v[1]);
}
intmain()
{
inti,j,n,c,x[6]={0},count=0;
intt[6];
intco[6];
cout<<"inputthevalueofthecoin:
";//输入硬币的面值
for(i=0;i<6;i++)
cin>>t[i];
cout<<"everycoinvalueis:
"<for(i=0;i<6;i++)
cout<cout<<"inputnumberofeverycoin:
";//输入对应面值硬币的个数
for(i=0;i<6;i++)
cin>>co[i];
cout<<"thenumberofeverycoinis:
"<for(i=0;i<6;i++)
cout<intm[7][11]={0};
n=5;
cout<<"inputthemoneyyouwanttochargewith:
";输入要找的钱数
cin>>c;
knapsack(co,t,c,n,m);
for(i=1;i<=n;i++)
{
for(j=1;j<=c;j++)
cout<cout<}
tback(m,t,c,n,x);
cout<<"theresultis:
";
for(i=0;i{
if(x[i])
{cout<count++;
}
}
cout<cout<<"latestnumber="<return0;
}
voidtback(intm[][11],intt[],intc,intn,intx[])//最优解
{
for(inti=0;i{
if(m[i][c]==m[i+1][c])
x[i]=0;
else
{
x[i]=1;
c-=t[i];
}
x[n]=(m[n][c])?
1:
0;
}
}