
算法分析例题
勤奋的懒羊羊o
东北林业大学 计算机科学与技术本科毕业
现东南大学网安硕士在读 欢迎交流
展开
-
NEFU19级算法设计与分析课程设计
算法课设(持续更新ing)分治策略动态规划贪心算法回溯算法分治策略动态规划4、台阶问题问题描述:有n级台阶,一个人每次上一级或者两级,问有多少种走完n级台阶的方法。实际情况:给定一个矩阵m,从左上角开始每次只能向右走或者向下走,最后达到右下角的位置,路径中所有数字累加起来就是路径和,返回所有路径的最小路径和,如果给定的m如下,那么路径1,3,1,0,6,1,0就是最小路径和,返回12.1 3 5 98 1 3 45 0 6 18 8 4 0代码如下#include <iost原创 2021-06-10 21:05:51 · 887 阅读 · 3 评论 -
随机数和数值随机算法
在计算机上无法产生真正的随机数,因此随机化算法中使用的随机数都是一定程度上随机的,即为伪随机数。通过线性同余法产生伪随机数:随机序列a0,a1,a2…an 满足随机投点计算pi值double Darts(int n) //n表示投掷的次数 { static RandomNumber dart; //随机数类 int k++; for(int i=1;i<=n;i++) { //fRandom()返回[0,1)之间的一个随机数 double x=dart.fRa原创 2021-05-30 09:25:08 · 933 阅读 · 4 评论 -
拉斯维加斯算法
拉斯维加斯算法能显著改进算法的有效性,甚至为某些迄今为止找不到有效算法的问题,也能得到满意结果。拉斯维加斯算法的一个显著特征是它所做的随机性策略可能找不到所需的解。典型的调用形式为bool success=LV(x,y),其中x是输入参数,当success值为true时,y返回问题的解。当success值为false时,算法未能找到问题的解,此时可对同一实例再次独立地调用相同的算法。n后问题...原创 2021-05-29 21:54:06 · 2600 阅读 · 1 评论 -
舍伍德型概率算法
舍伍德型概率算法可用于消除算法的时间复杂度与输入实例间的关系,可用于分析确定性算法的平均时间复杂度。舍伍德算法总是能求得问题的一个解,并且所求得的解总是正确的。但与其相对应的确定性算法相比较,舍伍德算法的平均时间复杂度并没有改进。舍伍德算法并不是避免算法的最坏情况行为**,而是设法消除了算法的不同输入实例对时间性能的影响。**对所有输入实例而言,舍伍德算法的运行时间比较均匀,其时间复杂度与原有的确定性算法在平均情况下的时间复习性相当。随机洗牌算法void shuffle(int cards[].原创 2021-05-29 19:08:48 · 3252 阅读 · 4 评论 -
图的m着色问题(子集树回溯法)
解空间:子集树题目比较容易,直接附代码代码#include <iostream>using namespace std;int n; //图的顶点数int x[100]; //当前解int a[100][100]; //邻接矩阵int m; //可用颜色数量int sum = 0; //当前已经找到的可m着色方案数bool OK(int t){ for (int i =..原创 2021-05-25 21:16:32 · 857 阅读 · 1 评论 -
最大团问题(子集树回溯法)
解空间:子集树可行性约束函数:顶点t到已经选入顶点集中每一个顶点之间都有边限界函数:有足够多的可选择的顶点使得算法有可能在右子树中找到更大的团(即cn+(n-t)>bestn)复杂度分析:O(n*2^n)需要掌握的习题代码#include <iostream>using namespace std;int n; //图的顶点个数int cn; //当前顶点数int x[100]; //当前解int bestx[100]; //当前最优解i原创 2021-05-25 08:41:35 · 1399 阅读 · 2 评论 -
0-1背包问题(子集树回溯法)
代码一:只考虑约束函数,即背包里的物品重量之和小于背包容量#include <iostream>using namespace std;int C,n,w[100],v[100];int BestX[100]; //BestX[i]=1代表物品i放入背包,0代表不放入int CurValue=0; //当前放入背包的总价值int CurWeight=0; //当前放入背包的总重量int BestValue=0; //最优值,当前的最大价值int x[100];原创 2021-05-01 21:51:21 · 1139 阅读 · 1 评论 -
N皇后问题(子集树、排列树回溯法)
> 这题既可以采用子集树也可用排列树问题描述解向量可行性约束限界约束代码一:子集树解决#include <iostream>using namespace std;int x[100]; //皇后的位置(i,x[i]),即x[i]表示皇后在i行的列位置int n; //棋盘规格int sum = 0;bool Place(int t) //实现限界约束判断{ for (int i = 1; i <t;i++)原创 2021-05-24 18:26:17 · 4250 阅读 · 0 评论 -
符号三角形数量(子集树回溯法)
问题描述可行性约束条件:当前符号三角形所包含的“+”和“-”个数均不超过n*(n+1)/4限界函数(无解的判断)n*(n+1)/2为奇数确定x[i+1]的值后,只要在前面确定的符号三角形的右边加一条边就扩展为x[1:i+1]所相应的符号三角形代码#include <iostream>using namespace std;int n = 0; //第一行符号的个数int half = 0; //符号总数的一半int count = 0; //"原创 2021-05-24 15:01:20 · 353 阅读 · 1 评论 -
批处理作业调度(排列树回溯法)
问题描述:每一个作业Ji都有两项任务分别在2台机器上完成。每个作业必须先有机器1处理,然后再由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理时间。则所有作业在机器2上完成处理时间和f=F2i,称为该作业调度的完成时间和。对于给定的n个作业,指定最佳作业调度方案,使其完成时间和达到最小。约束条件: 当前时间和小于当前最优解才有可能产生新的最优解,否则直接剪枝,不用再遍历这棵子树。作业流程: 画个简图加强一下作业工作流程排列树代码#i原创 2021-05-23 21:56:56 · 870 阅读 · 0 评论 -
装载问题(子集树回溯法)
题目最终要求的是选取全体集装箱的一个子集,使该子集中集装箱重量之和最接近第一艘轮船的载重量。所以是子集树约束函数:解向量的集装箱重量之和小于第一艘轮船载重量限界函数:当前载重量cw+剩余集装箱的重量rest≤当前最优载重量bestw考虑了限界函数的程序代码如下:#include <iostream>using namespace std;int C=0; //第一艘轮船的载重量 int n=0; //集装箱数量int原创 2021-05-23 17:34:41 · 704 阅读 · 2 评论 -
活动安排问题(贪心算法)
问题描述设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi。如果选择了活动i,则它在半开时间区间[si ,fi )内占用资源。若区间[si ,fi )与区间[sj,fj )不相交,则称活动i与活动j是相容的。当 si ≥ fj 或 sj ≥ fi 时,活动i与活动j相容。活动安排问题就是在所给的活动集合中选出最大的相容活动子集合。思路算法先按原创 2021-04-15 15:59:11 · 1792 阅读 · 0 评论 -
01背包问题(动态规划)
代码存一下,我个人觉得另外一种方式建立的动态规划方程比老师上课讲的那种要稍微容易理解一点,而且代码简单一点,先简单存一下,明天有时间写写两种方法的详解吧!这段代码前半部分的求最优值我前面有写过,这里就直接copy过来了#include<bits/stdc++.h>using namespace std;int dp[500][10000];//dp[i][j]表示前i个物品,背包容量是j的情况下的最大价值int v[10000];int w[10000];int main().原创 2021-04-15 00:26:29 · 141 阅读 · 2 评论 -
排列问题(n个数的全排列)(递归)
问题描述:设R={r1,r2,…,rn}是要迚行排列的n个元素,求R的全排列Perm®。问题分析:设(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。解决方案:1.递归关系:perm®由(r1)perm(R1),(r2)perm(R2) ,…, (rn)perm(Rn)构 成,其中Ri=R-{ri}。2.终止条件:n=1时,Perm®=r ,r是R中的唯一元素3.参数设置:待排序数组List,开始下标k,终止下标m实现思想:将整组数中的所有的数分别不第一个数交换原创 2021-04-12 22:38:15 · 1703 阅读 · 0 评论 -
最长公共子序列(动态规划)
问题描述最长公共子序列和最长公共字符串的概念最优子结构设序列X={x1,x2,…,xm}和Y={y1,y2…,yn}的最长公共子序列为Z={z1,z2,…,zk},则① 若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。② 若xm != yn且zk != xm,则Z是Xm-1和Y的最长公共子序列。③ 若下xm != yn且zk != yn,则Z是X和Yn-1的最长公共子序列。子问题的递归结构代码#include <iostream>us原创 2021-04-07 20:41:08 · 170 阅读 · 3 评论 -
集合最大元问题(分治+递归)
问题描述:在规模为n的数据元素集合中找出最大元。当n=2时,一次比较就可以找出两个数据元素的最大元和最小元。当n>2时,可以把n个数据元素分为大致相等的两半,一半有n/2个数据元素,而另一半有n/2个数据元素。 先分别找出各自组中的最大元,然后将两个最大元进行比较,就可得n个元素的最大元代码如下:#include <iostream>using namespace std;int Maxsum(int left,int right,int a[]){ if(left==原创 2021-03-30 21:17:26 · 600 阅读 · 0 评论 -
归并排序(合并排序)(分治)
代码一:非递归#include <iostream>#include <cstdlib>using namespace std;void Merge(int c[],int d[],int l,int m,int r)//合并c[l:m]和c[m+1:r]到的d[l:r]{ int i=l,j=m+1,k=i;//分别用i和j标记两个数组起始位置,作标记位 while((i<=m)&&(j<=r))//当两个数组都没有到达终点时原创 2021-03-15 18:50:23 · 163 阅读 · 0 评论 -
快速排序(分治+递归)
#include <iostream>#include <string.h>using namespace std;int Partition(int a[],int left,int right){ int key=a[left]; while(left<right) { while(left<right&&a[right]>=key) //从最右边寻找,当找到比key小的值时退出循环原创 2021-03-22 19:36:28 · 146 阅读 · 0 评论 -
棋盘覆盖(分治法+递归)
题意及思路如下图:代码如下:#include <iostream>#include <cstdlib>#include <string.h>using namespace std;int tile=1;int Board[100][100];/* * tr : 棋盘左上角顶点的行号,tc棋盘左上角顶点的列号 * dr : 特殊方格左上角顶点的行号,dc特殊方格左上角顶点的列号 * size :size = 2^k 棋盘规格为2^k*2^k */原创 2021-03-22 17:00:54 · 174 阅读 · 0 评论 -
矩阵连乘问题(动态规划)
题目描述:给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括号的方法表示矩阵连乘的次序,不同的计算次序计算量(乘法次数)是不同的,找出一种加括号的方法,使得矩阵连乘的次数最小。算法:构造递归解:设m[i,j]为矩阵链Ai…Aj的最优解的计算花费代价代码一:#include <iostream>#include <cstdlib>using namespace std;int m[100][100];int s[100原创 2021-03-29 17:10:52 · 662 阅读 · 1 评论 -
最大子段和问题(动态规划)
#include <iostream>#include <cstdlib>using namespace std;int d=0; //d变量记录取 最大子段和 最后一个元素的位置int a[101],b[101],c[101]; //c[i]是A[1:i]中必须包含元素A[i]的向前连续延伸的最大子段和,a[i]记录元素, //b[i]记录i位置元素是否包含在最大子段和里 int MaxSum(int n) //原创 2021-03-28 23:12:20 · 4106 阅读 · 2 评论