算法设计与分析的实验报告.docx
《算法设计与分析的实验报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析的实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
算法设计与分析的实验报告
实验一递归与分治策略
一、实验目的
1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
2.提高学生利用课堂所学知识解决实际问题的能力;
3.提高学生综合应用所学知识解决实际问题的能力。
二、实验内容
1、
①设a[0:
n-1]是已排好序的数组。
请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。
当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
②写出三分搜索法的程序。
三、实验要求
(1)用分治法求解上面两个问题;
(2)再选择自己熟悉的其它方法求解本问题;
(3)上机实现所设计的所有算法;
四、实验过程设计(算法设计过程)
1、已知a[0:
n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。
如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。
2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。
如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。
上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。
五、实验结果分析
二分搜索法:
三分搜索法:
时间复杂性:
二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(logn)。
(n代表集合中元素的个数)
O(3log3n)
空间复杂度:
O
(1)。
六、实验体会
本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。
七、附录:
(源代码)
#include
intbinarySearch(inta[],intx,intn)
{
intleft=0;intright=n-1;inti,j;
while(left<=right)
intmiddle=(left+right)/2;
if(x==a[middle]){i=j=middle;return1;}
if(x>a[middle])left=middle+1;
elseright=middle-1;
}
i=right;j=left;
return0;
intmain()
{inta[10]={0,1,2,3,4,5,6,7,8,9};
intn=10;
intx=9;
if(binarySearch(a,x,n))
cout<<"找到"<elsecout<<"找不到"< return0;} 实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。二、实验内容1、用两台处理机A和B处理n个作业。设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。由于各作业的特点和机器的性能关系,很可能对于某些i,有a[i]>=b[i],而对于某些就j,j!=i,有a[i]既不能将一个作业分开由两台机器处理,也没有一台机器能同时处理2个作业。设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。研究一个实例:(a[1],a[2],a[3],a[4],a[5],a[6])=(2,5,7,10,5,2);(b[1],b[2],b[3],b[4],b[5],b[6])=(3,8,4,11,3,4)。2、长江游艇俱乐部在长江上设置了n个游艇出租站1,2……n。游客可在游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金r(i,j)1<=i设计一个算法,计算出游艇1到游艇n所需最少租金。三、实验要求(1)用动态规划思想求解最优问题;(2)再选择自己熟悉的程序设计语言实现所有算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。2、对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i五、实验结果分析独立任务最优调度问题:租用游艇问题:时间复杂性:独立任务最优调度问题:O(n*Sum)六、实验体会对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。七、附录:(源代码)独立任务最优调度问题:usingSystem;namespacezydd{classProgram{staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result){for(inti=0;i{least[i]=99;}intaSum=0,bSum=0;for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
else
cout<<"找不到"< return0;} 实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。二、实验内容1、用两台处理机A和B处理n个作业。设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。由于各作业的特点和机器的性能关系,很可能对于某些i,有a[i]>=b[i],而对于某些就j,j!=i,有a[i]既不能将一个作业分开由两台机器处理,也没有一台机器能同时处理2个作业。设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。研究一个实例:(a[1],a[2],a[3],a[4],a[5],a[6])=(2,5,7,10,5,2);(b[1],b[2],b[3],b[4],b[5],b[6])=(3,8,4,11,3,4)。2、长江游艇俱乐部在长江上设置了n个游艇出租站1,2……n。游客可在游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金r(i,j)1<=i设计一个算法,计算出游艇1到游艇n所需最少租金。三、实验要求(1)用动态规划思想求解最优问题;(2)再选择自己熟悉的程序设计语言实现所有算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。2、对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i五、实验结果分析独立任务最优调度问题:租用游艇问题:时间复杂性:独立任务最优调度问题:O(n*Sum)六、实验体会对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。七、附录:(源代码)独立任务最优调度问题:usingSystem;namespacezydd{classProgram{staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result){for(inti=0;i{least[i]=99;}intaSum=0,bSum=0;for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
实验二动态规划——求解最优问题
1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;
1、用两台处理机A和B处理n个作业。
设第i个作业交给机器A处理时所需要的时间是a[i],若由机器B来处理,则所需要的时间是b[i]。
由于各作业的特点和机器的性能关系,很可能对于某些i,有a[i]>=b[i],而对于某些就j,j!
=i,有a[i]
既不能将一个作业分开由两台机器处理,也没有一台机器能同时处理2个作业。
设计一个动态规划算法,使得这两台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。
研究一个实例:
(a[1],a[2],a[3],a[4],a[5],a[6])=(2,5,7,10,5,2);(b[1],b[2],b[3],b[4],b[5],b[6])=(3,8,4,11,3,4)。
2、长江游艇俱乐部在长江上设置了n个游艇出租站1,2……n。
游客可在游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。
游艇出租站i到游艇出租站j之间的租金r(i,j)1<=i设计一个算法,计算出游艇1到游艇n所需最少租金。三、实验要求(1)用动态规划思想求解最优问题;(2)再选择自己熟悉的程序设计语言实现所有算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。2、对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i五、实验结果分析独立任务最优调度问题:租用游艇问题:时间复杂性:独立任务最优调度问题:O(n*Sum)六、实验体会对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。七、附录:(源代码)独立任务最优调度问题:usingSystem;namespacezydd{classProgram{staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result){for(inti=0;i{least[i]=99;}intaSum=0,bSum=0;for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
设计一个算法,计算出游艇1到游艇n所需最少租金。
(1)用动态规划思想求解最优问题;
(2)再选择自己熟悉的程序设计语言实现所有算法;
(3)分析所设计的算法的时间/空间复杂性。
1、对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。
2、对于给定的游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i五、实验结果分析独立任务最优调度问题:租用游艇问题:时间复杂性:独立任务最优调度问题:O(n*Sum)六、实验体会对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。七、附录:(源代码)独立任务最优调度问题:usingSystem;namespacezydd{classProgram{staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result){for(inti=0;i{least[i]=99;}intaSum=0,bSum=0;for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
独立任务最优调度问题:
租用游艇问题:
O(n*Sum)
对于算法来说,没有最好,只有更好,算法的结果不一定是最佳答案,但至少是最接近最佳答案的。
在权衡算法时间复杂度和空间复杂度的情况下,找到一个在时间和空间都能接受的算法才是上上之策。
usingSystem;
namespacezydd
classProgram
staticvoidDlrwZydd(int[]a,int[]b,intn,int[]least,string[]result)
for(inti=0;i{least[i]=99;}intaSum=0,bSum=0;for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
least[i]=99;
intaSum=0,bSum=0;
for(inti=0;i{aSum+=a[i];bSum+=b[i];}intSum=1+Math.Min(aSum,bSum);int[,]timeA=newint[n,Sum];int[,]timeB=newint[n,Sum];int[,]timeMax=newint[n,Sum];char[,]who=newchar[n,Sum];char[]tempRlt=newchar[n];for(inti=0;i<=a[0];i++){timeA[0,i]=i;if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
aSum+=a[i];
bSum+=b[i];
intSum=1+Math.Min(aSum,bSum);
int[,]timeA=newint[n,Sum];
int[,]timeB=newint[n,Sum];
int[,]timeMax=newint[n,Sum];
char[,]who=newchar[n,Sum];
char[]tempRlt=newchar[n];
for(inti=0;i<=a[0];i++)
timeA[0,i]=i;
if(i{timeB[0,i]=b[0];who[0,i]='b';}else{timeB[0,i]=0;who[0,i]='a';}timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);}if(a[0]<=b[0]){least[0]=a[0];tempRlt[0]='a';}else{least[0]=b[0];tempRlt[0]='b';}result[0]=newString(tempRlt);for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
timeB[0,i]=b[0];
who[0,i]='b';
timeB[0,i]=0;
who[0,i]='a';
timeMax[0,i]=Math.Max(timeA[0,i],timeB[0,i]);
if(a[0]<=b[0])
least[0]=a[0];
tempRlt[0]='a';
least[0]=b[0];
tempRlt[0]='b';
result[0]=newString(tempRlt);
for(intk=1;k{inttempSum=0;for(inttemp=0;temp<=k;temp++){tempSum+=a[temp];}for(inti=0;i<=tempSum;i++){timeA[k,i]=i;if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
inttempSum=0;
for(inttemp=0;temp<=k;temp++)
tempSum+=a[temp];
for(inti=0;i<=tempSum;i++)
{timeA[k,i]=i;
if(i{timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]]){timeB[k,i]=timeB[k-1,i]+b[k];who[k,i]='b';}else{timeB[k,i]=timeB[k-1,i-a[k]];who[k,i]='a';}}timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);}for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
timeB[k,i]=timeB[k-1,i]+b[k];
who[k,i]='b';
if((timeB[k-1,i]+b[k])<=timeB[k-1,i-a[k]])
timeB[k,i]=timeB[k-1,i-a[k]];
who[k,i]='a';
timeMax[k,i]=Math.Max(timeA[k,i],timeB[k,i]);
for(inti=tempSum+1;i{timeA[k,i]=tempSum;timeB[k,i]=0;}intflag=0;for(inti=0;i<=tempSum;i++){if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
timeA[k,i]=tempSum;
timeB[k,i]=0;
intflag=0;
if(timeMax[k,i]>0&&timeMax[k,i]{least[k]=timeMax[k,i];flag=i;}}tempRlt[k]=who[k,flag];for(inti=k;i>0&&flag>0;i--){if(tempRlt[i]=='a'){flag-=a[i];tempRlt[i-1]=who[i-1,flag];}if(tempRlt[i]=='b'){tempRlt[i-1]=who[i-1,flag];}}result[k]=newString(tempRlt);}}staticvoidMain(string[]args){constintN=6;int[]a=newint[N]{2,5,7,10,5,2};int[]b=newint[N]{3,8,4,11,3,4};int[]least=newint[N];string[]result=newstring[N];DlrwZydd(a,b,N,least,result);Console.WriteLine();for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
least[k]=timeMax[k,i];
flag=i;
tempRlt[k]=who[k,flag];
for(inti=k;i>0&&flag>0;i--)
if(tempRlt[i]=='a')
flag-=a[i];
tempRlt[i-1]=who[i-1,flag];
if(tempRlt[i]=='b')
result[k]=newString(tempRlt);
staticvoidMain(string[]args)
constintN=6;
int[]a=newint[N]{2,5,7,10,5,2};
int[]b=newint[N]{3,8,4,11,3,4};
int[]least=newint[N];
string[]result=newstring[N];
DlrwZydd(a,b,N,least,result);
Console.WriteLine();
for(inti=0;i{Console.WriteLine("按要求完成前{0}项任务的机器顺序为:"+result[i]+"时间为:{1}",i+1,least[i]);}}}} 实验三贪心算法一、实验目的1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求2.加深对贪婪法算法设计方法的理解与应用3.掌握将算法转化为计算机上机程序的方法4.培养学生应用所学知识解决实际问题的能力。二、实验内容1、设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti,1<=i<=n。应如何安排n个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是每个顾客等待服务时间的综合。2、一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。三、实验要求(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、首先将每个顾客所需要的服务时间从小到大排序。然后申请2个数组:st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n1.始点到终点的距离小于N,则加油次数k=0;2.始点到终点的距离大于N,①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
Console.WriteLine("按要求完成前{0}项任务的机器顺序为:
"+result[i]+"时间为:
{1}",i+1,least[i]);
实验三贪心算法
1.进一步理解算法设计的基本步骤及各步的主要内容、基本要求
2.加深对贪婪法算法设计方法的理解与应用
3.掌握将算法转化为计算机上机程序的方法
4.培养学生应用所学知识解决实际问题的能力。
1、设有n个顾客同时等待一项服务。
顾客i需要的服务时间为ti,1<=i<=n。
应如何安排n个顾客的服务次序才能使总的等待时间达到最小?
总的等待时间是每个顾客等待服务时间的综合。
2、一辆汽车加满油后可行驶n公里。
旅途中有若干个加油站。
设计一个有效算法,之处应在哪些加油站停靠加油,使沿途加油次数最少。
并证明算法能产生一个最优解。
(1)设计用贪婪法求解“最优服务次序问题”及“汽车加油问题”的算法;
(2)上机实现所设计的算法;
1、首先将每个顾客所需要的服务时间从小到大排序。
然后申请2个数组:
st[]是服务数组,st[j]为第j个队列上的某一个顾客的等待时间;su[]是求和数组,su[j]的值为第j个队列上所有顾客的等待时间;
2、设加油次数为k,每个加油站间距离为a[i];i=0,1,2,3……n
1.始点到终点的距离小于N,则加油次数k=0;
2.始点到终点的距离大于N,
①加油站间的距离相等,即a[i]=a[j]=L=N,则加油次数最少k=n;
②加油站间的距离相等,即a[i]=a[j]=L>N,则不可能到达终点;
③加油站间的距离相等,即a[i]=a[j]=L=0);④加油站间的距离不相等,即a[i]!=a[j],则加油次数k通过下面的算法求解。五、实验结果分析最优服务次序问题:时间复杂度为O(nlogn)汽车加油问题:时间复杂度为O(n)。六、实验体会 七、附录:(源代码)汽车加油问题:#include#includenamespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){Console.Write("请输入汽车加满油后可行驶路程:");intn=Convert.ToInt32(Console.ReadLine());Console.Write("请输入途经加油站总数:");intk=Convert.ToInt32(Console.ReadLine());int[]distance=newint[k+1];//加油站间距int[]note=newint[k];//记录加油站点Console.WriteLine("请输入加油站间距!");for(inti=0;i<=k;i++){//从始点起,加油站间距Console.Write("站点间距{0}:",i+1);distance[i]=Convert.ToInt32(Console.ReadLine());}intcount;//记录加油次数Problemp=newProblem();count=p.Greedy(distance,note,n);if(count>=0){if(count==0)Console.WriteLine("汽车不用加油就可到达终点!");else{Console.WriteLine("汽车在旅途中需加{0}次油!",count);Console.WriteLine("分别在以下加油站加了油:");for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
=0);
④加油站间的距离不相等,即a[i]!
=a[j],则加油次数k通过下面的算法求解。
最优服务次序问题:
时间复杂度为O(nlogn)
汽车加油问题:
时间复杂度为O(n)。
namespaceConsoleApplication1
Console.Write("请输入汽车加满油后可行驶路程:
");
intn=Convert.ToInt32(Console.ReadLine());
Console.Write("请输入途经加油站总数:
intk=Convert.ToInt32(Console.ReadLine());
int[]distance=newint[k+1];//加油站间距
int[]note=newint[k];//记录加油站点
Console.WriteLine("请输入加油站间距!
for(inti=0;i<=k;i++)
{//从始点起,加油站间距
Console.Write("站点间距{0}:
",i+1);
distance[i]=Convert.ToInt32(Console.ReadLine());
intcount;//记录加油次数
Problemp=newProblem();
count=p.Greedy(distance,note,n);
if(count>=0)
if(count==0)
Console.WriteLine("汽车不用加油就可到达终点!
Console.WriteLine("汽车在旅途中需加{0}次油!
",count);
Console.WriteLine("分别在以下加油站加了油:
for(inti=0;i{if(note[i]!=0){//输出需加油站点Console.WriteLine("第"+note[i]+"个加油站!");}}}}elseConsole.WriteLine("汽车无法到达终点!");Console.ReadKey();}}classProblem{publicintGreedy(int[]d,int[]note,intn){inti,j,s,add=0,p=0,k=d.Length;for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
if(note[i]!
=0)
{//输出需加油站点
Console.WriteLine("第"+note[i]+"个加油站!
Console.WriteLine("汽车无法到达终点!
Console.ReadKey();
classProblem
publicintGreedy(int[]d,int[]note,intn)
inti,j,s,add=0,p=0,k=d.Length;
for(i=0;i{if(d[i]>n){//不能到达目的地return-1;}}for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
if(d[i]>n)
{//不能到达目的地
return-1;
for(j=0,s=0;j{s+=d[j];if(s>n){//需要加油add++;note[p++]=j;s=d[j];}}returnadd;}}}实验四回溯法一、实验目的1.掌握能用回溯法求解的问题应满足的条件;2.加深对回溯法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。二、实验内容1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。2、设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。三、实验要求(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;(2)上机实现所设计的算法;(3)分析所设计的算法的时间/空间复杂性。四、实验过程设计(算法设计过程)1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。 ①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。 ②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。 ③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行; ④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。c.主函数调用一次Knapsack(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分 配工作; b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深 度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用): ①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行; ②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层 继续执行; ③采用for循环针对n个人对工作i进行分配(1≤j≤n): 1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配; 2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配; 3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对 第j+1个人进行分配; 4>当j>n时,for循环结束; ④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束; c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为 所求最小总费用。五、实验结果分析最小重量机器设计问题:程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!),故该算法的时间复杂度为O(n!)。工作分配问题:递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!),主函数调用递归函数backtrack(1,0),故该算法的时间复杂度为O(n!)。六、实验体会七、附录:(源代码)最小重量机器设计问题:#include#defineN1000usingnamespacestd;intn,m,d,cp=0,cw=0,sum=0;intc[N][N],w[N][N];voidbacktrack(inti){if(i>n){if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
s+=d[j];
if(s>n)
{//需要加油
add++;
note[p++]=j;
s=d[j];
returnadd;
实验四回溯法
1.掌握能用回溯法求解的问题应满足的条件;
2.加深对回溯法算法设计方法的理解与应用;
3.锻炼学生对程序跟踪调试能力;
4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
1、设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。
设w[i][j]是从供应商j处购得的部件i的重量,c[i][j]是相应的价格。
试设计一个算法,给出总价格不超过c的最小重量机器设计。
2、设有n件工作分配给n个人。
将工作i分配给第j个人所需的费用为c[i][j]。
试设计一个算法,为每一个人都分配1件不同的工作,并使总费用达到最小。
(1)用回溯法算法设计方法求解最小重量机器设计问题和工作分配问题;
1、a.部件有n个,供应商有m个,分别用w[i][j]和c[i][j]存储从供应商j处购得的部件i的重量和相应价格,d为总价格的上限。
b.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。
①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。
②若cw>=sum,则不是最优解,剪去相应子树,返回到i-1层继续执行。
③若i>n,则算法搜索到一个叶结点,用sum对最优解进行记录,返回到i-1层继续执行;
④用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。
c.主函数调用一次Knapsack
(1)即可完成整个回溯搜索过程,最终得到的sum即为所求最小总重量。
2、a.用c[i][j]存储将工作i分配给第j个人所需的费用,用v[j]标记第j个人是否已分
配工作;
b.用递归函数backtrack(i,total)来实现回溯法搜索排列树(形式参数i表示递归深
度,n用来控制递归深度,形式参数total表示当前总费用,s表示当前最优总费用):
①若total>=s,则不是最优解,剪去相应子树,返回到i-1层继续执行;
②若i>n,则算法搜索到一个叶结点,用s对最优解进行记录,返回到i-1层
继续执行;
③采用for循环针对n个人对工作i进行分配(1≤j≤n):
1>若v[j]==1,则第j个人已分配了工作,找第j+1个人进行分配;
2>若v[j]==0,则将工作i分配给第j个人(即v[j]=1),对工作i+1调用递归函数backtrack(i+1,total+c[i][j])继续进行分配;
3>函数backtrack(i+1,total+c[i][j])调用结束后则返回v[j]=0,将工作i对
第j+1个人进行分配;
4>当j>n时,for循环结束;
④当i=1时,若已测试完c[i][j]的所有可选值,外层调用就全部结束;
c.主函数调用一次backtrack(1,0)即可完成整个回溯搜索过程,最终得到的s即为
所求最小总费用。
最小重量机器设计问题:
程序中最大的循环出现在递归函数backtrack(i)中,而此函数遍历排列树的时间复杂度为O(n!
),故该算法的时间复杂度为O(n!
)。
工作分配问题:
递归函数backtrack(i,total)遍历排列树的时间复杂度为O(n!
),主函数调用递归函
数backtrack(1,0),故该算法的时间复杂度为O(n!
#defineN1000
usingnamespacestd;
intn,m,d,cp=0,cw=0,sum=0;
intc[N][N],w[N][N];
voidbacktrack(inti){
if(i>n){
if(cwsum=cw;return;}for(intj=1;j<=m;j++){cw+=w[i][j];cp+=c[i][j];if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
sum=cw;
return;
for(intj=1;j<=m;j++){
cw+=w[i][j];
cp+=c[i][j];
if(cwbacktrack(i+1);cw-=w[i][j];cp-=c[i][j];}}intmain(){cin>>n>>m>>d;for(inti=1;i<=n;i++){for(intj=1;j<=m;j++)cin>>c[i][j];sum+=c[i][1];}for(intk=1;k<=n;k++)for(intj=1;j<=m;j++)cin>>w[k][j];backtrack(1);cout<system("pause");return0;}
backtrack(i+1);
cw-=w[i][j];
cp-=c[i][j];
intmain(){
cin>>n>>m>>d;
for(inti=1;i<=n;i++){
for(intj=1;j<=m;j++)
cin>>c[i][j];
sum+=c[i][1];
for(intk=1;k<=n;k++)
cin>>w[k][j];
backtrack
(1);
cout<system("pause");return0;}
system("pause");
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1