10计本算法最大矩阵和01背包问题.docx
- 文档编号:25577489
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:18
- 大小:54.86KB
10计本算法最大矩阵和01背包问题.docx
《10计本算法最大矩阵和01背包问题.docx》由会员分享,可在线阅读,更多相关《10计本算法最大矩阵和01背包问题.docx(18页珍藏版)》请在冰豆网上搜索。
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 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]+""); } } 结果: 五、实验总结 一、本次实验让我认识到了: 我对动态规化的认识远远不够,因为用了穷举法还不知道是怎么回事,后来经老师指导才明白,原来是有重复运算。 后来重新思考,也写出经效率较高的算法,没有重复运算了,应该是用了动态规化的思想。 二、原来不怎么会调试,经过同学帮助现在已经比较熟练掌握但还须加强。 三、最长下坡一题,因为之前有做过,所以就直接用老师的算法了。 (已经理解)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 10 算法 最大 矩阵 01 背包 问题