C++U6-06 - 一维线性动态规划

小虾同学 / 2024-03-04 / 原文

上节课作业:

链接:https://pan.baidu.com/s/17Fei1SuGEk5pnSspf_hprg?pwd=hq04
提取码:hq04

 

动态规划

 

 

[最长上升子序列]

 

 

本题采用动态规划 。
数据储存,设定数组a[]用于存储数字序列 ,设定dp[]数组用于统计上升的序列个数;
遍历组数a[],在遍历的过程中如果出现了数字上升的情况,就使用动态规划累计当前的最优解;
动态转移方程为 ,dp[i] = max(dp[i],dp[j]+1);
最后,遍历数组dp[] , 找出dp[]数组中的最大值。

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N], dp[N];
int n;
int ans;
int main(){
    cin >> n;
    for (int i=1; i<=n; i++) {
        cin >> a[i];
        dp[i] = 1;
        for (int j=1; j<i; j++) {
            if (a[j] < a[i]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
            ans = max(ans, dp[i]); 
        }
    }   
    cout << ans << endl;
    return 0;
}
View Code

[导弹拦截]

 

 

还是最长序的模型

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N], dp[N];
int n;
int ans;
int main(){
    cin >> n;
    for (int i=1; i<=n; i++) {
        cin >> a[i];
        dp[i] = 1;
        for (int j=1; j<i; j++) {
            if (a[j] >= a[i]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        ans = max(ans, dp[i]); 
    }   
    cout << ans << endl;
    return 0;
}
View Code

 

[编辑距离]

 

 

本题采用动态规划 。

数据储存,设定数组a[] 与数组 b[] ,用于存储AB字符串;

使用二维数组f,一维表示a字符串长度为i,二维表示b字符串长度为j;

因为增加一个字符相当于b字符串删掉一个字符,修改一个字符相当于不增也不减,相当于两个字符相等时的情况

初始化时当a为0位时,操作个数肯定是b的长度(即增加b长度个字符)

同理,当b为0位时,操作个数肯定是a的长度(即删除a长度个字符)

动态转移方程:

if(a[i] == b[j]) f[i][j] = f[i-1][j-1];

else f[i][j] = min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1]) + 1;

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

const int N = 2020;
char a[N], b[N];
int al, bl;
int f[N][N];

int main() {

    cin >> a+1 >> b+1;
    al = strlen(a+1), bl = strlen(b+1);
    for (int i=1; i<=al; i++) f[i][0] = i;    // 代码设计技巧,对应一个空字符的修改次数
    for (int i=1; i<=bl; i++) f[0][i] = i;    // 代码设计技巧,对应一个空字符的修改次数
    for (int i=1; i<=al; i++) {
        for (int j=1; j<=bl; j++) {
            if (a[i] == b[j]) {
                f[i][j] = f[i-1][j-1];
            } else {
                f[i][j] = min(f[i-1][j-1], min(f[i-1][j], f[i][j-1]))+1;
            }
        }
    }
    cout << f[al][bl] << endl;

    return 0; 
}
View Code

 

 

作业:

链接:https://pan.baidu.com/s/1ASA3fair7LakNs5MEPrRQQ?pwd=jij9
提取码:jij9