实验二 动态规划算法文档格式.docx
- 文档编号:21062289
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:12
- 大小:145.39KB
实验二 动态规划算法文档格式.docx
《实验二 动态规划算法文档格式.docx》由会员分享,可在线阅读,更多相关《实验二 动态规划算法文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
这里使用的char数组,可以按字符输出,若改为string类型,
//执行printf("
%c"
A[m-1])就会报错;
charA[100],B[100];
//输入的两个串a和b
//这里定义全局变量可以不赋值0,因为全局变量自动赋值0;
intc[max][max];
//记录最长公共子序的长度;
intb[max][max];
//记录状态号;
voidLCS(intm,intn)
{
if(m==0||n==0)
{
return;
}
elseif(b[m][n]==1)
LCS(m-1,n-1);
printf("
A[m-1]);
}
elseif(b[m][n]==2)
m=m-1;
LCS(m,n);
elseif(b[m][n]==3)
n=n-1;
}
voidLCS_length(intm,intn)
for(inti=1;
i<
=m;
i++)
for(intj=1;
j<
=n;
j++)
{
if(A[i-1]==B[j-1])
{
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;
}
intmain()
printf("
请输入两个待测的字符串:
\n"
);
scanf("
%s"
&
A);
B);
intm=strlen(A);
//m为A串长度;
intn=strlen(B);
//n为B串长度;
LCS_length(m,n);
其最长公共子序的长度为:
%d\n"
c[m][n]);
其最长公共子序为:
"
LCS(m,n);
return0;
(2)运行结果为:
(3)算法思路:
最长公共子序列的结构有如下表示:
设序列X=<
x1,x2,…,xm>
和Y=<
y1,y2,…,yn>
的一个最长公共子序列Z=<
z1,z2,…,zk>
,则:
1.若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
2.若xm≠yn且zk≠xm,则Z是Xm-1和Y的最长公共子序列;
3.若xm≠yn且zk≠yn
,则Z是X和Yn-1的最长公共子序列。
其中Xm-1=<
x1,x2,…,xm-1>
,Yn-1=<
y1,y2,…,yn-1>
,Zk-1=<
z1,z2,…,zk-1>
。
基本题二:
最大字段和问题
1、熟悉最长最大字段和问题的算法;
2、进一步掌握动态规划算法;
若给定n个整数组成的序列a1,a2,a3,……an,求该序列形如ai+ai+1+……+an的最大值。
三,实验源代码:
intN;
//表示一个数组的长度值;
intdp[max];
//记录以i为结尾的最大子段和;
//通过dp数组记录最优下标的start和end;
voidMaxsum(inta[])
intmaxx=0;
intend,start;
=N;
if(dp[i-1]>
0)
dp[i]=dp[i-1]+a[i];
}
else
dp[i]=a[i];
if(maxx<
=dp[i])
maxx=dp[i];
end=i;
start=end;
inti;
for(i=start-1;
i>
=0;
i--)
if(dp[i]>
=0)
start=i;
break;
i++;
start=i;
MaxSum:
dp[end]);
Beststart:
start);
Bestend:
end);
请输入一组数据的元素个数:
%d"
N);
int*a=newint[N+1];
请输入元素的值:
scanf("
a[i]);
Maxsum(a);
deletea;
(2)运行结果:
其实,我们在选择一个元素a[j]的时候,只有两种情况,将a[i]至a[j-1]加上,或者从a[j]以j为起点开始。
我们用一个数组dp[i]表示以i为结束的最大子段和,对于每一个a[i],加上dp[i-1]成为子段,或以a[i]开始成为新段的起点。
因为我们只需要记录dp值,所以复杂度是O(n)。
这就是最大子段和的动态规划算法。
我们甚至不需要dp数组,只需要定义一个dp变量,因为最后要求的dp值也是最大的,所以我们可以在求dp的时候更新为最大的。
提高题一:
用动态规划法求解0/1背包问题
一、实验要求与目的
1、掌握动态规划算法求解问题的一般特征和步骤。
2、使用动态规划法编程,求解0/1背包问题。
二、实验内容
1、问题描述:
给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大?
2、算法描述。
3、程序实现;
给出实例测试结果。
三.
(1)实验源代码:
//用动态规划的方法求解0/1背包问题
//要求:
//input:
n表示总共有n种物品
//W表示每种物品的重量
//V表示每种物品的价值
//c表示背包的容量
intn,c;
intdp[1005][1005];
voidKnapsack(intV[],intW[],intc,intn,intdp[][1005])
inti,j;
intjMax=min(W[n]-1,c);
//这里必须是W[n]-1,否则,在W[n-1]时刻也是合法情况;
for(j=0;
=jMax;
dp[n][j]=0;
//i=n,j<
wn;
for(j=W[n];
=c;
dp[n][j]=V[n];
for(i=n-1;
1;
jMax=min(W[i]-1,c);
for(j=0;
dp[i][j]=dp[i+1][j];
//若小于当前的背包容量,则不装入;
for(j=W[i];
dp[i][j]=max(dp[i+1][j],dp[i+1][j-W[i]]+V[i]);
//比较装入的代价,谋求最大代价;
dp[1][c]=dp[2][c];
if(c>
=W[1])
dp[1][c]=max(dp[1][c],dp[2][c-W[1]]+V[1]);
voidTraceback(intdp[][1005],intW[],intc,intn,intx[])
//x数组用来存放是否第i个元素被装栽进来
n;
if(dp[i][c]==dp[i+1][c])
x[i]=0;
x[i]=1;
c=c-W[i];
x[n]=(dp[n][c])?
1:
0;
if(x[i]==1)
printf("
第%d个物品装入\n"
i);
请输入物品的数量和背包的容量:
%d%d"
n,&
c);
int*W=newint[n];
int*V=newint[n];
int*x=newint[n];
W[0]=0,V[0]=0,x[0]=0;
请输入每个物品的重量:
W[i]);
请输入每个物品的价值:
V[i]);
Knapsack(V,W,c,n,dp);
Traceback(dp,W,c,n,x);
(3)算法思路:
令V(i,j)表示在前i(1<
=i<
=n)个物品中能够装入容量为就j(1<
=j<
=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:
(1)
V(i,0)=V(0,j)=0
(2)
V(i,j)=V(i-1,j)
wi
V(i,j)=max{V(i-1,j),V(i-1,j-wi)+vi)}j>
wi
(1)式表明:
如果第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包;
第
(2)个式子表明:
如果第i个物品的重量小于背包的容量,则会有一下两种情况:
(a)如果把第i个物品装入背包,则背包物品的价值等于第i-1个物品装入容量位j-wi
的背包中的价值加上第i个物品的价值vi;
(b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。
显然,取二者中价值最大的作为把前i个物品装入容量为j的背包中的最优解。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验二 动态规划算法 实验 动态 规划 算法