10计本算法最大矩阵和01背包问题.docx

上传人:b****9 文档编号:25577489 上传时间:2023-06-09 格式:DOCX 页数:18 大小:54.86KB
下载 相关 举报
10计本算法最大矩阵和01背包问题.docx_第1页
第1页 / 共18页
10计本算法最大矩阵和01背包问题.docx_第2页
第2页 / 共18页
10计本算法最大矩阵和01背包问题.docx_第3页
第3页 / 共18页
10计本算法最大矩阵和01背包问题.docx_第4页
第4页 / 共18页
10计本算法最大矩阵和01背包问题.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

10计本算法最大矩阵和01背包问题.docx

《10计本算法最大矩阵和01背包问题.docx》由会员分享,可在线阅读,更多相关《10计本算法最大矩阵和01背包问题.docx(18页珍藏版)》请在冰豆网上搜索。

10计本算法最大矩阵和01背包问题.docx

10计本算法最大矩阵和01背包问题

实验报告7

课程数据结构与算法实验名称动态规划(四)第页

班级10计本学号105032010111姓名陈兴灶

实验日期:

2012年4月09日报告退发(订正、重做)

一、实验目的

掌握动态规划的原理和应用。

二、实验环境

1、微型计算机一台

2、WINDOWS操作系统,JavaSDK,Eclipse开发环境

三、实验内容

必做题:

1、给定n种物品和一背包。

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

问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

假设i的取值从1开始。

2、给定一个数列,该数列中,元素值可能为正也可能为负,请设计一个程序,求该序列中一个子序列,该子序列元素之和最大。

附加题:

1、如以下的左图所示,现有一个矩形序列,这些矩形宽度为1,请设计程序,求这些矩形序列合并而成的最大矩形面积。

上图中的矩形高度分别为:

2145133,最优解为上图中左图所示,最优值为:

8

四、实验步骤和结果

第一题:

01背包问题

packageshiyan_7;

importjava.util.Scanner;

publicclassZOP{

staticint[]weight;

staticint[]value;

staticintn;

staticintc;

staticint[][]b;

publicstaticvoidMaxvalue(int[]weight,int[]value,intc,int[][]b)

{

for(inti=0;i<=n;i++)

{

b[0][i]=0;

b[i][0]=0;

}

for(inti=1;i<=n;i++)

for(intj=1;j<=c;j++)

{

if(j

b[i][j]=b[i-1][j];

else

{

intw=j-weight[i];

if(b[i-1][j]>b[i-1][w]+value[i])

b[i][j]=b[i-1][j];

elseb[i][j]=b[i-1][w]+value[i];

}

}

}

publicstaticvoidmain(String[]args)

{

Scannersc=newScanner(System.in);

System.out.println("请输入物品的总个数:

");

n=sc.nextInt();

System.out.println("请输入背包的容量:

");

c=sc.nextInt();

weight=newint[n+1];

value=newint[n+1];

b=newint[n+1][c+1];

System.out.println("请输入各个物品的重量:

");

for(inti=1;i<=n;i++)

{

weight[i]=sc.nextInt();

}

System.out.println("请输入各个物品的价值:

");

for(intj=1;j<=n;j++)

{

value[j]=sc.nextInt();

}

Maxvalue(weight,value,c,b);

System.out.println("背包问题的最优值:

"+b[n][c]);

}

}

结果:

第二题:

求子序列元素和最大

packageshiyan_7;

importjava.util.Scanner;

publicclassSumMax1{

publicstaticint[]a;

publicstaticint[]start;

publicstaticint[]end;

publicstaticintn;

publicstaticintt;

publicstaticints=0;

publicstaticinte=0;

publicstaticintmax[];

publicstaticintk=1;

publicstaticvoidsummax(int[]a)

{

for(inti=0;i

{

if(a[i]>=0)

{

e=i;

max[k]+=a[i];t=max[k];

if(max[k-1]>t)

{

e=i-2;

t=max[k-1];

}

}

elseif(a[i]<0&&max[k]+a[i]>=0)

{

intj=k;

k++;

max[k]+=max[j]+a[i];

}

else

{

k++;

}

}

}

publicstaticvoidmain(String[]args)

{

Scannersc=newScanner(System.in);

System.out.println("输入数组长度");

n=sc.nextInt();

a=newint[n];

System.out.println("输入数组各元素");

for(inti=0;i

a[i]=sc.nextInt();

max=newint[n+1];

summax(a);

System.out.println("输出最大值");

System.out.println(t);

System.out.println("输出最优解(从后往前输出)");

inti=e,b=0;

while(i>=0&&b!

=t)

{

System.out.print(a[i]+"");

b=b+a[i];

i--;

}

}

}

结果:

第三题:

packageshiyan_7;

importjava.util.Arrays;

publicclassLongest{

/**

*@paramargs

*/

publicstaticvoidmain(String[]args){

//TODOAuto-generatedmethodstub

int[][]c={//该数组用来存放区域内各点高度

{1,2,3,4,5},

{16,17,18,19,6},

{15,24,25,20,7},

{14,23,22,21,8},

{13,12,11,10,9}

};

int[][]m=newint[c.length][c.length];//该数组用来存放最优值,m[i][j]存放区域中第i行第j列点为起始的最长坡长

initArraym_pre(m);//对m数组进行初始化,将各元素初始化为0

int[][]pre=newint[c.length][c.length];//该数组用来存放每点的最优值对应的前驱结点,用来构造最优解,0表示该点没有前驱,1表示前驱点在右,2表示前驱点在左,3表示前驱点在上,4表示前驱点在下。

initArraym_pre(pre);//对pre数组进行初始化,全部初始化为0

Element[]e=newElement[c.length*c.length];//该数组用来存放区域的每个点信息对象,该信息对象包含描述一个区域点所需要的信息,共3个成员:

区域i,j坐标和该点高度

initArrare(c,e);//对数组e进行初始化,为区域中的每个点生成一个信息对象,存入数组e中,且对数组中e的元素按照点的高度进行排序

longestLRUP(c,m,pre,e);//求以各点为起点的最长坡长,结果存入m中,且将最优值对应的前驱结点存入pre中,用来构造最优解。

show2DArray(m);

show2DArray(pre);

System.out.println(longest(m));//显示问题最优值,即区域最长下坡

showLongestRoute(c,m,pre);//显示问题最优解

}

privatestaticvoidshow2DArray(int[][]m){

//TODOAuto-generatedmethodstub

for(inti=0;i

for(intj=0;j

System.out.print(m[i][j]+"");

}

System.out.println();

}

}

privatestaticvoidshowLongestRoute(int[][]c,int[][]m,int[][]pre){

//该方法利用求最优值过程中得到的信息构造问题最优解

ElementstartPoint=longesStarttPoint(c,m);//先确定最长坡长的起始点的信息对象

inti=startPoint.i;//起始点i坐标

intj=startPoint.j;//起始点j坐标

System.out.print(c[i][j]+"");//显示起始点

while(pre[i][j]!

=0){//该循环根据pre数组,依次的显示出最长坡长上的每个点的高度

switch(pre[i][j]){

case1:

//如果值为1表示前驱点为左边点

j--;

break;

case2:

//如果值为2表示前驱点为右边点

j++;

break;

case3:

//如果值为3表示前驱点为上边点

i--;

break;

case4:

//如果值为4表示前驱点为下边点

i++;

break;

}

System.out.print(c[i][j]+"");

}

}

privatestaticElementlongesStarttPoint(int[][]c,int[][]m){

//该方法用来求最长坡长的起始点,返回该点的信息对象

intcurrentI=0;

intcurrentJ=0;

intcurrentLongest=0;

for(inti=0;i

for(intj=0;j

if(currentLongest

currentLongest=m[i][j];

currentI=i;

currentJ=j;

}

}

}

returnnewElement(currentI,currentJ,c[currentI][currentJ]);

}

privatestaticintlongest(int[][]m){

//该方法返回问题的最优值

intcurrentLongest=0;

for(inti=0;i

for(intj=0;j

if(currentLongest

currentLongest=m[i][j];

}

}

returncurrentLongest;

}

privatestaticvoidlongestLRUP(int[][]c,int[][]m,int[][]pre,Element[]e){

//该方法为关键方法,求问题的最优值,并保存到中,同时将各点最优值前驱放入到per中

for(inti=0;i

Elementx=e[i];

intleft=0;

intright=0;

intup=0;

intdown=0;

intmax=0;

if(x.j>0){//要注意最左边的点没有左边点

if(x.h>c[x.i][x.j-1])

left=m[x.i][x.j-1];

if(max

max=left;

pre[x.i][x.j]=1;

}

}

if(x.j

if(x.h>c[x.i][x.j+1])

right=m[x.i][x.j+1];

if(max

max=right;

pre[x.i][x.j]=2;

}

}

if(x.i>0){//要注意最上边点没有上边点

if(x.h>c[x.i-1][x.j])

up=m[x.i-1][x.j];

if(max

max=up;

pre[x.i][x.j]=3;

}

}

if(x.i

if(x.h>c[x.i+1][x.j])

down=m[x.i+1][x.j];

if(max

max=down;

pre[x.i][x.j]=4;

}

}

m[x.i][x.j]=max+1;

}

}

privatestaticvoidinitArraym_pre(int[][]m_pre){

//对参数m_pre对应的二维数组进行初始化,将所有元素初始化为0

for(inti=0;i

for(intj=0;j

m_pre[i][j]=0;

}

}

}

privatestaticvoidinitArrare(int[][]c,Element[]e){

//利用区域原始数据来初始化数组e,即对数组c中的每个点,构造该点信息对象,且存入数组e中

intk=0;

for(inti=0;i

for(intj=0;j

e[k++]=newElement(i,j,c[i][j]);

}

}

Arrays.sort(e);//对数组e元素根据点的高度进行排序

}

}

packageshiyan_7;

publicclassElementimplementsComparable{//区域点信息类,必须实现Comparable接口

inti;//点的i坐标

intj;//点的j坐标

inth;//点的高度

publicElement(inti,intj,inth){

super();

this.i=i;

this.j=j;

this.h=h;

}

@Override

publicintcompareTo(Elemente){//因为要对这个类的对象进行排序,所以该类需要实现Comparable接口

//此方法为该接口申明的方法,子类中必须实现,当使用Arrays的sort方法对该类对象进行排序时

//会调用该对象的此方法,进行对象间的比较,根据比较结果排序

if(e.h>this.h)

return-1;//返回负数,表示当前对象小

if(e.h

return1;//返回正数,表示当前对象大

return0;//返回零,表示两个对象大小相等

}

}

结果:

附加题:

packageshiyan_7;

importjava.util.Scanner;

publicclassAreaMax{

publicstaticint[][]b;

publicstaticintk;

publicstaticintn;

publicstaticintr;

publicstaticint[]max;

publicstaticint[]x;

publicstaticint[]y;

publicstaticvoidareamax(int[]a)

{

for(inti=1;i<=n;i++)

b[i][i-1]=0;

for(inti=1;i<=n;i++)

{intt=b[i][i-1];

inte=a[i];

for(intj=i;j<=n;j++)

{

if(a[j]

b[i][j]=(j-i+1)*e;

if(t

{

t=b[i][j];

y[i]=j;

}

}

max[i]=t;

}

}

publicstaticintmax(int[]a)

{

intm=max[1];

k=1;

for(inti=2;i<=n;i++)

if(m

{

m=max[i];

k=i;

}

returnm;

}

publicstaticvoidmain(String[]args){

//TODOAuto-generatedmethodstub

Scannersc=newScanner(System.in);

System.out.println("输小长方形个数(每个小长方形的底为1)");

n=sc.nextInt();

int[]a=newint[n+1];

b=newint[n+1][n+1];

max=newint[n+1];

y=newint[n+1];

System.out.println("输入各小长方形的高");

for(inti=1;i<=n;i++)

{

a[i]=sc.nextInt();

}

areamax(a);

System.out.println("输出最大值");

System.out.println(max(max));

System.out.println("最优解为");

for(inti=k;i<=y[k];i++)

System.out.print(a[i]+"");

}

}

结果:

 

五、实验总结

一、本次实验让我认识到了:

我对动态规化的认识远远不够,因为用了穷举法还不知道是怎么回事,后来经老师指导才明白,原来是有重复运算。

后来重新思考,也写出经效率较高的算法,没有重复运算了,应该是用了动态规化的思想。

二、原来不怎么会调试,经过同学帮助现在已经比较熟练掌握但还须加强。

三、最长下坡一题,因为之前有做过,所以就直接用老师的算法了。

(已经理解)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1