当前位置:文档之家› 动态规划算法实验

动态规划算法实验

一、实验目的 (2)
二、实验内容 (2)
三、实验步骤 (3)
四.程序调试及运行结果分析 (5)
附录:程序清单(程序过长,可附主要部分) (7)
实验四动态规划算法的应用
一、实验目的
1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。

2.熟练掌握分阶段的和递推的最优子结构分析方法。

3.学会利用动态规划算法解决实际问题。

二、实验内容
1.问题描述:
题目一:数塔问题
给定一个数塔,其存储形式为如下所示的下三角矩阵。

在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。

请找出一条路径,使路径上的数值和最大。

输入样例(数塔):
9
12 15
10 6 8
2 18 9 5
19 7 10 4 16
输出样例(最大路径和):
59
题目二:最长单调递增子序列问题(课本184页例28)
设有由n个不相同的整数组成的数列,记为:a(1)、a(2)、……、a(n)且a(i)<>a(j) (i<>j) 若存在i1<i2<i3< …<ik 且有a(i1)<a(i2)< …<a(ik),则称为长度为k的不下降序列。

请编写算法求出一个数列的最长不下降序列。

题目三 0-1背包问题
给定n种物品和一个背包。

物品i的重量是wi,其价值为vi,背包的容量为c,。

问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品只有两个选择:装入或不装入,且不能重复装入。

输入数据的第一行分别为:背包的容量c,,物品的个数n。

接下来的n 行表示n个物品的重量和价值。

输出为最大的总价值。

输入样例:
20 3
11 9
9 10
7 5
输出样例
19
2.数据输入:个人设定,由键盘输入。

3.要求:
1)上述题目任选一做。

上机前,完成程序代码的编写
2)独立完成实验及实验报告
三、实验步骤
1.理解算法思想和问题要求;
2.编程实现题目要求;
3.上机输入和调试自己所编的程序;
4.验证分析实验结果;
5.整理出实验报告。

一.实验目的
二.问题描述
三.算法设计
包含:数据结构与核心算法的设计描述、函数调用及主函数设计、主要算法流程图等
动态规划主要针对最优化问题,它的决策不是线性的而是全面考虑各种不同的情况分别进行决策,最后通过多阶段决策逐步找出问题的最终解。

从数塔问题的特点来看,不难发现解决问题的阶段划分,应该是自上而下逐层决策。

不同于贪婪策略的是做出的不是唯一的决策,要从全局出发。

0-1背包问题:用f记录不同承重量背包的总价值,w记录不同物品的重量,v记录不同物品的价值。

在双重循环中,在放入第i个物品前后,检验不同j承重量背包的总价值,如果放入第i个物品后比放入前的价值提高了,则修改j承重量背包的价值,否则不变。

四.程序调试及运行结果分析
1.数塔问题:改正错误后,运行程序,构建一个三层数塔,依次输入塔中的数据后,运行结果为:路径和最大值为32 路径为9 15 8 经过验证,结果正确。

2.0-1背包问题:解决错误,运行程序。

如图所示输入数据后,成功输出正确结果 19.
五.实验总结
对于这次的实验,我感觉到比较吃力。

首先动态规划不同于贪婪算法,它是全面考虑各种不同的情况分别进行决策的。

解决问题需要分阶段进行,更复杂一些。

所以思考问题需要考虑的更加全面周到,在这一点上我做的还不够好。

另外对于数塔问题,我首次使用三维数组,由于以前接触的少所以理解就使我感到比较困难。

通过本次实验,我还是认识到自身有很多的不足,我也会在以后的学习中慢慢改进,脚踏实地,勤以补拙。

附录:程序清单(程序过长,可附主要部分)数塔问题代码如下:
#include<iostream>
using namespace std;
int main()
{
int a[50][50][3],i,j,n;
cout<<"你要构建一个几层数塔?"<<endl;
cin>>n;
cout<<"请依次输入数塔中的数据:"<<endl;
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
cin>>a[i][j][1];
a[i][j][2]=a[i][j][1];
a[i][j][3]=0;
}}
for (i=n-1;i>=1;i--)
for (j=1 ;j<=i;j++)
if (a[i+1][j][2]>a[i+1][j+1][2])
{
a[i][j][2]=a[i][j][2]+a[i+1][j][2];
a[i][j][3]=0;
}
else
{
a[i][j][2]=a[i][j][2]+a[i+1][j+1][2];
a[i][j][3]=1;
}
cout<<"路径和最大值为:"<<a[1][1][2]<<" ";
j=1;
cout<<"路径为:";
for( i=1 ;i<= n-1;i++)
{
cout<<a[i][j][1]<<" ";
j=j+a[i][j][3];
}
cout<<a[n][j][1]<<endl;
return 0;}
0-1背包问题代码如下:
#include <stdio.h>
#include <conio.h>
#include <string.h>
int f[1010],w[1010],v[1010];
int max(int x,int y)
{
if(x>y) return x;
return y;
}
int main()
{
int t,m,i,j;
memset(f,0,sizeof(f));
scanf("%d %d",&t,&m);
for(i=1;i<=m;i++)
scanf("%d %d",&w[i],&v[i]);
for(i=1;i<=m;i++)
{
for(j=t;j>=w[i];j--)
{
f[j]=max(f[j-w[i]]+v[i],f[j]);
}
}
printf("%d",f[t]);
printf("\n");
getch();
return 0;
}。

相关主题