动态规划
来源:互联网 发布:王朔人品知乎 编辑:程序博客网 时间:2024/06/16 21:45
动态规划
采用动态规划求解的问题需要具有两个特性:
- 最优子结构(Optimal Substructure):问题的一个最优解中所包含的子问题的解也是最优的。
- 重叠子问题(Overlapping Subproblems):用递归算法对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。
综上所述,动态规划的关键是 —— 记忆,空间换时间,不重复求解,从较小问题解逐步决策,构造较大问题的解。
1、动态规划一般可分为线性规划、区域规划、树形规划、背包动态规划四类。
2、动态规划两个重要概念:状态和状态转移方程。
3、最长公共子串、最长公共子序列、最长递增子序列。
最长公共子串与最长公共子序列的区别:子串要求在原字符串中是连续的,而子序列则只需保持相对顺序,并不要求连续。
最长公共子序列(LSC)
#include<iostream>#include<algorithm>#include<vector>#include<string>using namespace std;int array[2000][2000];int dp[2000][2000];int main(){//有两条随机序列,如 1 3 4 5 5 6 和 2 4 5 5 7 6,则它们的最长公共子序列便是:4 5 5 6,最长公共子串为4 5 5。 string str1, str2; memset(dp, 0, sizeof(dp)); while (cin >> str1 >> str2) { int la = str1.length();//字符串1的长度 int lb = str2.length();//字符串2的长度 for (int idx = 1; idx <= la; idx++) { for (int jdx = 1; jdx <= lb; jdx++) { if (str1[idx-1] == str2[jdx-1])//两个字符串中有相同的字符 { dp[idx][jdx] = dp[idx - 1][jdx - 1] + 1; } else dp[idx][jdx] = max(dp[idx - 1][jdx], dp[idx][jdx - 1]); } } cout << dp[la][lb] << endl;//统计子字符序列的个数 } system("pause"); return 0;}
最长公共子串
#include<iostream>#include<algorithm>#include<vector>#include<string>using namespace std;int array[2000][2000];int dp[2000][2000];int main(){ string str1, str2; memset(dp, 0, sizeof(dp)); while (cin >> str1 >> str2) { int biggest = 0; int la = str1.length();//字符串1的长度 int lb = str2.length();//字符串2的长度 for (int idx = 1; idx <= la; idx++) { for (int jdx = 1; jdx <= lb; jdx++) { if (str1[idx-1] == str2[jdx-1])//两个字符串中有相同的字符 { dp[idx][jdx] = dp[idx - 1][jdx - 1] + 1; if (dp[idx][jdx] > biggest) biggest = dp[idx][jdx]; } else dp[idx][jdx] = 0; } } cout << biggest << endl;//统计子串序列的个数 } system("pause"); return 0;}
最长递增子序列(LIC)
#include<iostream>#include<algorithm>#include<vector>#include<string>using namespace std;int main(){ int n = 0; int dp[1000];//存放子序列中数字的个数 int arr[1000];//序列 while (cin >> n) { int res = 0; memset(arr, 0, sizeof(arr)); memset(dp, 0, sizeof(dp)); for (int idx = 0; idx < n; idx++) cin >> arr[idx]; for (int idx = 0; idx < n; idx++) { dp[idx] = 1; for (int jdx = 0; jdx < idx; jdx++) { if (arr[idx] > arr[jdx]) dp[idx] = max(dp[idx], dp[jdx] + 1); } res = max(res, dp[idx]); } cout << res << endl; }return 0;}
最长递增子串
#include<iostream>#include<algorithm>#include<queue>using namespace std;int main(){//最长递增子串int n = 0;int arr[1000];//序列queue<int> q;while (cin >> n){int res = 0;int count = 1;memset(arr, 0, sizeof(arr));for (int idx = 0; idx < n; idx++){cin >> arr[idx];q.push(arr[idx]);}while (!q.empty()){int temp = q.front();q.pop();if (q.size() && temp < q.front())count++;elsecount = 1;res = max(res, count);}cout << res << endl;}system("pause");return 0;}
阅读全文
0 0
- 动态规划!!!动态规划!!!
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 动态规划
- 【Java】简单入门
- WOJ1386-Number Tricks
- 今天是教师节
- vue(1)
- 练习2: 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
- 动态规划
- WOJ1406-Internet Service Providers
- 二叉树的遍历
- 网易2018校招编程题
- 70. Climbing Stairs
- 【数据结构】B树的特性
- 练习3: 求1+2!+3!+...+20!的和
- WOJ1414-URL
- 行内元素如何设置宽高