算法复习

本文详细介绍了大整数乘法的分治法,最接近点对问题,矩阵连乘问题的动态规划解决方案,以及活动安排、背包问题和旅行售货员问题的贪心算法。同时,探讨了0-1背包、N皇后问题和子集和问题的回溯法策略。最后,简要提及了红黑树的概念。
摘要由CSDN通过智能技术生成

大整数乘法 分治法

分治法思想:将一个规模为n的问题,分解成k个规模较小的子问题,子问题和原问题相同,且相互独立。然后递归的解决这些子问题,最终合并成原问题的解。所以说其是一种自底向上的算法。
代码

//头文件
#pragma once
class Big_number_multiply
{
   
public:
	long long BigNumberMultiply(long long X, long long Y, int N);
};

 //.cpp 文件
#include "Big_number_multiply.h"
#include <algorithm>

long long  Big_number_multiply::BigNumberMultiply(long long X, long long Y, int N) 
{
   
	if (N<=2)  // 已经包含了 X,Y =0 的情况,
	{
   
		return X * Y;
	}
	else
	{
   
		long long A = (X / pow(10, N / 2)) * pow(10, N / 2);// 注意A需要恢复到10 ^(N/2)
		long long B = X - A;
		long long C = Y / pow(10, N / 2) * pow(10, N / 2);
		long long D = Y - C;
		long long AC = BigNumberMultiply(A, C, N / 2);
		long long BD = BigNumberMultiply(B, D, N / 2);
		long long ABCD = BigNumberMultiply((A-B), (D-C), N / 2)+ AC + BD;
		return AC + BD + ABCD;
	}
}

//main
//大整数乘法  --分治法
Big_number_multiply bnm;
cout << bnm.BigNumberMultiply(1234, 1234, 4)<<endl;

最接近点对 分治法

一维的和二维的,下面是二维的伪码
伪代码

bool bestFasten(int S , int d)
{
   
	m = S 按照X排序的中点
	将区域S 以m为分界线分成S1 ,S2
	bestFasten(s1,d1);
	bestFasten(s2,d2);
	d = min(d1,d2)
	对区域S 中的Y 坐标进行排序,然后以m为轴,以d为边界,将S划分为一个两个子区域S3,S4
	按照y从小到大的顺序从S3中选一个点A,然后以A点为轴心,
	在S4区域中选取(A-d,A+d)的区域在S4 中最多有6个与之结合的点(鸽舍原理)设其距离为dm
	dmin = min(dm,d)
	return true;
}

矩阵连乘问题-- 动态规划

动态规划的思路:
将一个规模为n的问题,分解成k个规模较小的子问题,这些子问题和原问题相同,但是互相有联系,然后递归的求解最优值,最后求出原问题的最优解。
设计步骤:
1,寻找最优解的性质
2,递归的定义最优解
3,使用自底向上的思路求解最优解
4,得到最终的最优解
代码:

最优解的性质:
m[i][j]=0		(i=j)
m[i][j] = m[i][k]+m[k+1][j] + p[i-1]p[k]p[j]   (i<j)

//.h文件
#pragma once
#include<vector>
using namespace std;
class Matrix_continue_multiply
{
   
public:
	void MatrixContinueMultiply(vector<int> demension,int n);
public:
	int  m[10][10];
	int  s[10][10];
};


//cpp文件
#include "Matrix_continue_multiply.h"
#include<iostream>
using namespace std;
// m[i][j]  代表的是从 i 到 j 的矩阵相乘的最优值
// s[i][j]  代表的是断开的位置k
void Matrix_continue_multiply::MatrixContinueMultiply(vector<int> p,int n) 
{
   
	for (int i = 1; i <= n; i++)
	{
   
		m[i][i] = 0;  //自己乘自己为0
	}

	// r 记录长度
	for (int r = 2; r<=n; r++) 
	{
   
		for (int i = 1;i<=n-r+1;i++) 
		{
   
			int j = r + i - 1;
			m[i][j] = m[i + 1][j] + p[i - 1]*p[i]*p[j];
			s[i][j] = i;
			for (int k =i+1;k<j;k++) 
			{
   
				int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
				if (t< m[i][j]) 
				{
   
					m[i]
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值