动态规划作业

本文介绍两种经典动态规划算法的应用实例:矩阵链乘的最优求解及最长公共子序列的高效计算方法。矩阵链乘部分通过递归方式输出最优括号化方案;最长公共子序列部分则采用迭代法实现,最终输出两个字符串的最长公共子序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

矩阵链乘

#include <iostream>
using namespace std;   
#define MAX 50  
#define inf 99999999  
int p[MAX+1];             //存储各个矩阵的列数以及第一个矩阵的行数(作为第0个矩阵的列数)   
int m[MAX][MAX];          //m[i][j]存储子问题的最优解    
int s[MAX][MAX];           //s[i][j]存储子问题的最佳分割点  
int n;                    //矩阵个数  
void matrix()    {     
    int i,j,k;    
    for(i=0;i<n;i++)    
        m[i][i]=0;                  //最小子问题在对角线全为0   

    for(i=2;i<=n;i++){
        for(j=0;j<n-i+1;j++){                           
            m[j][j+i-1]=inf;     
            for(k=0;k<i-1;k++){                  //k代表分割点    
                if(m[j][j+i-1]>m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i]){    
                    m[j][j+i-1]=m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i];    
                    s[j][j+i-1]=k;              //记录分割点    
                }    
            }    
        }       
    }           
}    

void printmatrix(int l,int r){//递归打印输出    
    if(l==r)    
        printf("A%d",l);    
    else{    
        cout << "(";
        printmatrix(l,l+s[l][r]);    
        printmatrix(l+s[l][r]+1,r);    
        cout << ")";  
    }    
}    
int main()    
{    
    int i;  
    cout << "输入矩阵个数: ";
    cin >> n;
    cout << "\n" << "输入矩阵的行和列: " << endl; 
    for(i=0;i<n+1;i++){  
        cin >> p[i];
    }  
    matrix();    
    cout << "矩阵连乘最小次数 " << m[0][n-1] << endl; 
    printmatrix(0,n-1);
    cout << endl;    
    return 0;    
} 

结果

这里写图片描述

最长公共子序列(不需要额外辅助变量)

#include <iostream>
#include <string>
using namespace std;

void LCS(int c[][100],int m,int n, string str1, string str2);
void print_LCS(int c[][100], string str1, int i, int j);
int main(){
    string str1,str2;
    int m,n;
    int c[100][100];
    cout << "输入str1字符串:";
    cin >> str1;
    cout << "输入str2字符串: "; 
    cin >> str2;
    m = str1.length();
    n = str2.length();
    for(int i=0;i<=m;i++){
        c[i][0] = 0;
    }
    for(int i=0;i<=n;i++){
        c[0][i] = 0;
    }
    LCS(c,m,n,str1,str2);
    for(int i=0;i<=m;i++){
        for(int j=0;j<=n;j++){
            cout << c[i][j];
        }
        cout << endl;
    }
    print_LCS(c,str1,m,n);
    return 0;   
}

void LCS(int c[][100],int m,int n, string str1, string str2){
    for(int i=1; i<=m; i++){
        for(int j=1; j<=n; j++){
            if(str1[i-1] == str2[j-1]){
                c[i][j] = c[i-1][j-1]+1;
            } else if(c[i-1][j]>=c[i][j-1]){
                c[i][j] = c[i-1][j];
            } else {
                c[i][j] = c[i][j-1];
            }
        }
    }
}

void print_LCS(int c[][100], string str1, int i, int j){
    if(i==0 || j == 0){
        return ;
    }
    if((c[i][j]-1) == c[i-1][j-1] && (c[i-1][j]== c[i][j-1])){
        print_LCS(c,str1,i-1,j-1);
        cout << str1[i-1];
    }else if(c[i][j] == c[i-1][j]){
        print_LCS(c,str1,i-1,j);
    } else {
        print_LCS(c,str1,i,j-1);
    }
}

结果

这里写图片描述

整数划分

#include<stdio.h>  
#include<iostream.h>  
using namespace std;  
int q(int n,int m){  
    if((n==1)||(m==1))   
            return 1;  
    else if(n<m)   
            return q(n,n);  
    else if(n==m)   
            return q(n,m-1)+1;  
    else   
        return q(n,m-1)+q(n-m,m);  
}  
int main(){  
    int x;  
    cin >>x;  
    printf("%d\n",q(x,x));  // 防止杀毒程序删除exe文件 
    return 0;  
}

结果

整数划分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值