IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【算法设计与分析】动态规划 -> 正文阅读

[数据结构与算法]【算法设计与分析】动态规划

矩阵连乘问题

计算A1A2An的最小代价方法(最小时间复杂度,乘法次数),返回最优值和最优解。若A是pq矩阵,B是qr矩阵,则AB的代价是O(pqr)
在这里插入图片描述
在这里插入图片描述

void MatrixChain(int *p,int n,int **m,int **s)
{      for (int i = 1; i <= n; i++) m[i][i] = 0;//对角线值初始化为0
        for (int r = 2; r <= n; r++)//一共有r个矩阵相乘
           for (int i = 1; i <= n - r+1; i++) 
           {
              int j=i+r-1;//Ai*Ai+1*....*Aj(共有r个矩阵相乘,j-i+1=r)
              m[i][j] = m[i][i]+m[i+1][j]+ p[i-1]*p[i]*p[j];//k=i的情况
              s[i][j] = i;
              for (int k = i+1; k < j; k++)//依次列举k=i+1的情况
               {
                 int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                 if (t < m[i][j]) { m[i][j] = t; s[i][j] = k;}
              }       
             }
}
#include "stdio.h"
#include "math.h"
#include <conio.h>
void MatrixChain( long int *p, long int n,long int m[100][100],long int s[100][100])
{   long int i,j,r,k,t;
    for (i=1; i<=n; i++) m[i][i]=0;
    for (r=2; r<=n; r++)
        for (i=1; i<=n-r+1; i++)
    	{ j=i+r-1;
            m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];
            s[i][j]=i;
            for ( k=i+1; k<j; k++)
    		{  t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
                      if (t< m[i][j]) { m[i][j]=t; s[i][j]=k; }
    		}    	}  }


void Traceback( long int i, long int j,long int s[100][100])
{
    if (i==j) return;
    Traceback(i,s[i][j],s);
    Traceback(s[i][j]+1,j,s);
    printf("%ld,%ld,%ld\n",i,j,s[i][j]);
}
int main()
{
   long int p[100];    long int n;     long int m[100][100],s[100][100];
    n=6;     p[0]=30;    p[1]=35;    p[2]=15;    p[3]=5;    p[4]=10;    p[5]=20;   p[6]=25;
    MatrixChain( p, n, m,s);
    printf("zuiyouzhi=%ld",m[1][6]);
    printf("\ns[1][6]=%ld\n",s[1][6]);
    Traceback( 1, n, s);
    getch();}

在这里插入图片描述

最长公共子序列问题

在这里插入图片描述
1 设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则
(1)若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。
(2)若xm≠yn且zk≠xm,则Z是Xm-1和Y的最长公共子序列。
(3)若xm≠yn且zk≠yn,则Z是X和Yn-1的最长公共子序列。

其中,Xm-1={x1,x2,…,xm-1}, Yn-1={y1,y2,…,yn-1} Zk-1={z1,z2,…,zk-1}

2 得出最优值的递归关系
在这里插入图片描述
3 自底向上计算最优值
例子:
在这里插入图片描述

#include <stdio.h>
#include <string.h>
#define MAXLEN 100
void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{
//
    int i, j;
    //初始化为0
    for(i = 0; i <= m; i++)        c[i][0] = 0;
    for(j = 1; j <= n; j++)        c[0][j] = 0;
    //双层循环
    for(i = 1; i<= m; i++)
        for(j = 1; j <= n; j++)
        {
            if(x[i] == y[j])
            {
                c[i][j] = c[i-1][j-1] + 1;
                b[i][j] = 1;//标记为左上角
            }
            else if(c[i-1][j] >= c[i][j-1])
            {
                c[i][j] = c[i-1][j];
                b[i][j] = 2;//上
            }
            else
            {
                c[i][j] = c[i][j-1];
                b[i][j] = 3;//左
            }
        }
}
void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{
    if(i == 0 || j == 0)        return;
    if(b[i][j] == 1)
    {
        PrintLCS(b, x, i-1, j-1);
        printf("%c ", x[i]);
    }
    else if(b[i][j] == 2)
        PrintLCS(b, x, i-1, j);
    else
        PrintLCS(b, x, i, j-1);
}
int main(int argc, char **argv)
{
    char x[MAXLEN] = {" ABCBDABPP"};
    char y[MAXLEN] = {" BDCABAPQ"};
    int b[MAXLEN][MAXLEN];
    int c[MAXLEN][MAXLEN];
    int m, n;
    m = strlen(x);
    n = strlen(y);
    LCSLength(x, y, m, n, c, b);
    PrintLCS(b, x, m, n);
    return 0;
}

时间复杂性:计算最优值O(mn), 构造最优解O(m+n),总体O(mn)
空间复杂性:使用数组C和B,O(mn)

最大子段和问题

在这里插入图片描述
1简单算法
O(n3)
O(n2)
2 分冶策略 T(n)=O(nlogn)

int MaxSum(int *a, int left, int right)
{
    int sum=0, leftsum, rightsum, center, s1=0, lefts=0, rights=0, s2=0;
    if( left==right)//最小区间
        if(a[left]>0)  return a[left];
        else return 0;
    else
    {
        center=(left+right)/2;
        leftsum=MaxSum(a,left,center);
        rightsum=MaxSum(a,center+1, right);
        for(i=center; i>=left; i--)  //一个i值对应一个子段和
        {
            lefts=lefts+a[i];
            if(lefts>s1)  s1=lefts;//从center开始往回找到最大的和
        }
        for(i=center+1; i<=right; i++)
        {
            rights=rights+a[i];
            if(rights>s2)  s2=rights;//从center+1往后找到最大的和
        }
        sum=s1+s2;
        if(sum<leftsum)   sum=leftsum;
        if(sum<rightsum)  sum=rightsum;
    }
    return sum;
}

3 动态规划算法
子问题的界定:
前边界为1,后边界i,b[i]是A[1…i]中必须包含元素A[i]的向前连续延伸的最大字段和

递推方程:
b[i]=max{b[i-1]+A[i], A[i]} i=2,…,n

b[1]=A[1] 若A[1]>0
b[1]=0 否则

最大子段和为:
在这里插入图片描述

int  MaxSum(int n, int *a, int *c, int *d)
{  
   int *b, sum; sum=0; b[0]=0;
   for(i=1; i<=n; i++)
    {   if(b[i-1]>0)//b[i]=max{b[i-1]+A[i],  A[i]} 
         { b[i]=b[i-1]+a[i]; c[i]=1;}//c[i]=1标记,b[i]=b[i-1]+A[i]
         else  {b[i]=a[i]; c[i]=0;}//b[i]=A[i]
         if(b[i]>sum)  {sum=b[i]; (*d)=i;}
     }
     return sum;
}

void output(int *c, int d)
{ 
   int i=d;
	do
	{   if(i==d)
		  printf("=%d",a[i]);
	   else
	      printf("+%d",a[i]);
	}while(c[i--]==1);//如果c[i]==1 就往前走,来判断第一个数的下标,c[i]==0,就退出
}

凸多边形最优三角剖分

目前还理解

0-1背包问题

在这里插入图片描述

void Knapsack(int * v, int *w, int c, int n, int m[10][10])
{
	int jMax,j,i; 
	jMax=(w[n]-1)<c?(w[n]-1):c; //jMax:列数
	for ( j=0; j<=jMax; j++)		m[n][j]=0;//最后一行全为0
	for ( j=w[n]; j<=c; j++)		m[n][j]=v[n];//将最后一行中,小于背包容量的全为赋值为选最后物品的价值
	for( i=n-1; i>1; i--)
	{        
	    jMax=(w[i]-1)<c?(w[i]-1):c;
		for ( j=0; j<=jMax; j++)//背包容量小于该行物品容量
		m[i][j]=m[i+1][j];//不选
	    for ( j=w[i]; j<=c; j++)
		m[i][j]=m[i+1][j]>(m[i+1][j-w[i]]+v[i])?m[i+1][j]:(m[i+1][j-w[i]]+v[i]);
	}
	m[1][c]=m[2][c];
if(c>=w[1]) 
m[1][c]=m[1][c]>(m[2][c-w[1]]+v[1])?m[1][c]:(m[2][c-w[1]]+v[1]);
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:38:43  更:2022-04-01 23:39:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:33:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码