算法总结-DP入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LZUwujiajun/article/details/81355225

概览

一个问题必须有重叠子问题最优子结构(这个问题的最优解可以由其子问题的最优解有效的构造出来)才可以用动态规划解决。

解决方式

  1. 递推:自底向上
  2. 递归自顶向下

贪心与动态规划的区别
贪心是局部最优解,在每一次选择中,选了就不后悔。动态规划则考虑所有的子问题,选择能笑到最后的。

数塔问题

//数塔问题,将一些数字排成塔状,第n层有n个数字,现在从第一层走到第n层
//最后路径上最大的数字之和为多少
//用DFS做复杂度O(2^n),存在大量的重复子问题
//状态转移方程:dp[i][j] = max(dp[i+1][j],dp[i+1][j+1])+f[i][j]
#include<cstdio>
#include<algorithm>
using namespace std;

int f[1000][1000] = {0};
int dp[1000][1000] = {0};

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		for(int j = 1; j <= i;j++){
			scanf("%d",&f[i][j]);
		}
	}
	
	for(int j = 1;j <= n;j++){
		dp[n][j] = f[n][j];
	}
	
	for(int i = n-1;i >=1;i--){
		for(int j = 1;j <= i;j++){
			dp[i][j] = max(dp[i+1][j],dp[i+1][j+1])+f[i][j];
		}
	}
	
	printf("%d",dp[1][1]);
} 

最大连续子列和

//最大连续子序列和
//dp[i]表示以i结尾的数列的最大值
//状态转移方程 dp[i] = max(arr[i],dp[i-1]+arr[i]) 
#include<cstdio>
#include<algorithm>
using namespace std;


int main(){
	int arr[] = {-2,11,-4,13,-5,-2};
	int dp[6];
	dp[0] = arr[0];
	
	for(int i = 1;i < 6;i++){
		dp[i] = max(arr[i],dp[i-1]+arr[i]);
	}
	
	int maxSum = -1;
	for(int i = 0;i < 6;i++){
		if(dp[i] > maxSum){
			maxSum = dp[i];
		}
	}
	
	printf("%d",maxSum);
} 

最长不下降子序列

//最长不下降子序列
//状态转移方程dp[i] = max(1,dp[j]+1),条件:arr[j] <= arr[i] && dp[j]+1>dp[i] 
//时间复杂度O(n^2) 

#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
	int n;
	scanf("%d",&n);
	int arr[1000],dp[1000];
	for(int i = 0;i < n;i++){
		scanf("%d",&arr[i]);
	}
	
	int ans = -1;
	for(int i = 0;i < n;i++){
		dp[i] = 1;
		for(int j = 0;j < i;j++){
			if(arr[j] <= arr[i] && dp[j]+1>dp[i]){
				dp[i] = dp[j]+1;
			}
		}
		ans = max(ans,dp[i]);
		
	} 
	
	printf("%d",ans);
} 

最长公共子序列

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

//最长公共子序列
//d[i][j]表示A的i号位和B的j号位之前的最长公共子序列
//d[i][j] = dp[i-1][j-1]+1;A[i] = b[i]
//d[i][j] = max(dp[i-1][j],dp[i][j-1]);A[i] != b[i]
int main() {

    int dp[100][100];

    string A = " sadstory";
    string B  = " adminsorry";

    int lenA = A.size()-1;
    int lenB = B.size()-1;

    for(int i = 0;i <= lenA;i++){
        dp[i][0] = 0;
    }

    for(int i = 0;i <= lenB;i++){
        dp[0][i] = 0;
    }

    for(int i = 1;i <= lenA;i++){
        for(int j = 1;j <= lenB;j++){
            if(A[i] == B[j]){
                dp[i][j] = dp[i-1][j-1]+1;
            }else{
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
            }
        }
    }

    printf("%d",dp[lenA][lenB]);



}

猜你喜欢

转载自blog.csdn.net/LZUwujiajun/article/details/81355225