1、实验标题
1、 矩阵连乘 2、最长公共子序列 3、最大子段和
4、 凸多边形最优三角剖分 5、流水作业调度
6、0-1背包问题 7、最优二叉搜索树
实验目的
掌握动态规划法的基本思想和算法设计的基本步骤。
实验内容与源码
1、 矩阵连乘
#include
2、],int b[][4],int c[][4],int ra ,int ca,int rb ,int cb )
{
if(ca!=rb) cerr<<"矩阵不可乘";
for(int i=0;i 3、in(int *p,int n,int m[][4],int s[][4])
{
for(int i=1;i<=n;i++) m[i][i]=0;//对角线
for(int r=2;r<=n;r++)//外维
for(int i=1;i<=n-r+1;i++)//上三角
{
int j=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k 4、 int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t 5、
{
cout<<"(A"<>w;
int p[w],s[w][w];
cout<<"输入矩阵A1维数:";
ci 6、n>>p[0]>>p[1];
for(int i=2 ; i<=w ; i++)
{
int m = p[i-1];
cout<<"输入矩阵A"<>p[i-1]>>p[i];
if(p[i-1] != m)
{
cout< 7、
}
运行结果
2、 最长公共子序列
#include 8、[i-1][j]>=s[i][j-1]
//flag[i][j]==-1为c[i-1][j] 9、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;
flag[i][j] = 0;
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j] = c[i-1][j];
flag[i][j] = 1;
}
else
10、 {
c[i][j] = c[i][j-1];
flag[i][j] = -1;
}
}
return c[m][n];
}
//求出最长公共子序列
char* getLCS(char *x, char *y,int len,char *lcs)
{
int i = strlen(x);
int j = strlen(y);
while(i&&j)
{
if(flag[i][j]==0)
{
11、 lcs[--len] = x[i-1];
i--;
j--;
}
else if(flag[i][j]==1)
i--;
else
j--;
}
return lcs;
}
int main()
{
int i;
cout<<"请输入字符串x:"< 12、
cin>>str2;
int lcsLen = LCSLength(str1,str2);
cout<<"最长公共子序列长度:"< 13、 namespace std;
int MaxSubSum(int *a,int left,int right)
{
int sum=0;
if(left==right) sum=a[left]>0?a[left]:0;
else
{
int center = (left+right)/2;
//最大子段和在左边
int leftsum=MaxSubSum(a,left,center);
//最大子段和在右边
int rightsum=MaxSubS 14、um(a,center+1,right);
//最大子段和在中间
int s1=0;
int lefts=0;
for(int i=center;i>=left;i--)
{
lefts+=a[i];
if(lefts>s1) s1=lefts;
}
int s2=0;
int rights=0;
for(int i=center+1;i<=right;i++)
15、 {
rights+=a[i];
if(rights>s2) s2=rights;
}
sum=s1+s2;//前后子段和相加
//判断最大子段和
if(sum>leftsum)sum=leftsum;
if(sum>rightsum) sum=rightsum;
}
return sum;
}
int MaxSum(int *a,int n)
{
return MaxSubSum(a,1,n-1);
}
16、int main()
{
int a[8]={2,-3,-5,4,1,7,1,-5};
cout<<"最大子段和为:"< 17、 if(b>sum) sum=b;
}
return sum;
}
int main()
{
int a[8]={2,-3,-5,4,1,7,1,-5};
cout<<"最大子段和为:"< 18、
int y;
};
int distance(point X, point Y)//两点距离
{
int dis = (Y.x-X.x)*(Y.x-X.x) + (Y.y-X.y)*(Y.y-X.y);
return (int)sqrt(dis);
}
int w(point a, point b, point c)//权值
{
return distance(a,b) + distance(b,c) + distance(a,c);
}
bool JudgeInput()//判断是否能构成凸多边形
{
poi 19、nt *v; //记录凸多边形各顶点坐标
int *total; //记录坐标在直线方程中的值
int m,a,b,c;
cout<<"请输入凸多边形顶点个数:";
cin>>m;
int M = m-1;
for(int i=0 ; i 20、
for(int j=0 ; j 21、
b = v[j].x - v[j+1].x;
c = b * v[j].y - a * v[j].x;
}
for(int k=0 ; k 22、[k] < 0)
{
q = q+1;
}
}
if((p>0 && q>0) || (p==0 && q==0))
{
cout<<"无法构成凸多边形!"< 23、v;
for(int i=1 ; i<=M ; i++)
t[i][i] = 0;
for(int r=2 ; r<=M ; r++)
for(int i=1 ; i<=M-r+1 ; i++)
{
int j = i+r-1;
t[i][j] = t[i+1][j] + w(v[i-1],v[i],v[j]);
s[i][j] = i;
for(int k=i+1 ; k 24、 {
int u = t[i][k] + t[k+1][j] + w(v[i-1],v[k],v[j]);
if(u < t[i][j])
{
t[i][j] = u;
s[i][j] = k;
}
}
}
return true;
}
void Traceback(int i, int j, int **s) 25、
{
if(i == j)
return;
Traceback(i,s[i][j],s);
Traceback(s[i][j]+1,j,s);
cout<<"三角形:v"< 26、 //记录凸多边形各顶点坐标
int *total; //记录坐标在直线方程中的值
int M=0;
t = new int *[N];
s = new int *[N];
for(int i=0 ; i 27、)
{
if(minWeightTriangulation())
{
Traceback(1,M,s);
cout< 28、 public:
/* int operator<=(Jobtype a)const
{
return(key<=a.key);
}*/
int key;
int index;
bool job;
};
void sort(Jobtype *d,int n)
{
int i,j;
Jobtype temp;
bool exchange; //交换标志
for(i = 0;i < n;i ++){ //最多做n-1 29、趟排序
exchange = false; //本趟排序开始前,交换标志应为假
for(j = n - 1;j >= i;j --)
if(d[j+1].key < d[j].key){
temp = d[j+1];
d[j+1] = d[j];
d[j] = temp;
exchange=true; //发生了交换,故将交换标志置为真
}
if(! 30、exchange) //本趟排序未发生交换,提前终止算法
return;
}
}
int FlowShop(int n,int *a,int *b,int *c)
{
Jobtype *d = new Jobtype[n];
for(int i=0;i 31、
sort(d,n);;
int j=0;
int k=n-1;
for(int i=0;i 32、 {
j+=a[c[i]];
k=j 33、";
for(int i=0;i 34、行结果:
6、0-1背包问题
#include 35、的最大价值
w为重量数组,v为价值数组
n为物品个数,c为开始容量
则m[1][c]即此背包能剩下的最大价值
*/
void knapsack(int **m,int n, int c,int *w, int *v)
{
int jMax = min(w[n]-1,c);//前n-1个物品
for(int j=0;j<=jMax;j++)
m[n][j]=0;
for(int j=w[n];j<=c;j++)
m[n][j]=v[n];
for(int i=n-1;i>1;i--)
{
36、 jMax=min(w[i]-1,c);
for(int j=0;j<=jMax;j++)
m[i][j] = m[i+1][j];
for(int j=w[i];j<=c;j++)
m[i][j] = max(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]=max(m[1][c],m[2][c-w[1]]+v[1]);
}
//找出最优解,0表示不能装 37、1表示能装
void traceback(int **m,int n,int c,int *x,int *w)
{
for(int i=1;i 38、w=new int[N+1];
int **m=new int* [N+1];
int *x=new int [N+1];
for(int i=0;i 39、v[i];
knapsack(m,N,C,w,v);
traceback(m,N,C,x,w);
cout<<"最优值:"< 40、lude 41、rySearchTree(double *a,double *b,int n)
{
int s[N][N];
double m[N][N];
double w[N][N];
int i,j,l,r;
for(i=1; i<=n+1; i++)
{
m[i][i-1] = b[i-1];
w[i][i-1] = b[i-1];
}
for(l=1; l<=n; l++)
{
for(i=1; i<=n-l+1; i++)
{
42、 j = l+i-1;
m[i][j] = MAX;
w[i][j] = w[i][j-1] + a[j] +b[j];
for(r=i; r<=j; r++)
{
double k = m[i][r-1] + w[i][j] + m[r+1][j];
if(k 43、 s[i][j] = k;
}
}
}
}
cout< 44、 cin>>a[i];
sum += a[i];
}
cout<<"请输入每个虚拟键的概率:"<






