动态规划思想 / 步骤 :
- 先将 当前要求 总结成一个 精炼的 小问题 ,
- 然后 将 求解题目 转换为 求解N个 小问题 ,
- 每个小问题的 求解过程相同 ,但是 过程涉及 的 数据 是不同的 ,
- 例如第三个 小问题的 结果 也 会影响 第 四个 小问题 的 求解。(看情况保存结果)
class Solution {
public:
bool find(string str,vector<string>&k)
{for (auto tem : k){if (tem == str)return true;}return false;
}
bool wordBreak(string s, vector<string>&wordDict) {vector<bool> dp(s.length() + 1); dp[0] = true;for (int i = 1; i < s.length() + 1; i++){for (int j = 0; j < i; j++){if (dp[i - j - 1] && (find(s.substr(i - j - 1, j + 1), wordDict))){dp[i] = true;break;}}}return dp[s.length()];}
};
三角形中最小路径之和
class Solution {
public:int minimumTotal(vector<vector<int>>& triangle) {if(triangle.size() == 1)return triangle[0][0];for(int i = triangle.size()-2;i>= 0;i--){for(int j = 0; j < triangle[i].size();j++){triangle[i][j] += (triangle[i+1][j] < triangle[i+1][j+1]) ? triangle[i+1][j] : triangle[i+1][j+1];}}return triangle[0][0];}
};
class Solution {
public:int uniquePaths(int m, int n) {int arr[100][100];for(int i = 0; i < m;i++)for(int j = 0 ;j < n ;j++)arr[i][j] = 1;for(int i = 1;i < m;i++)for(int j = 1;j < n;j++)arr[i][j] = arr[i-1][j]+arr[i][j-1];return arr[m-1][n-1];}
};
01背包
子问题 :
子问题 : 在 x 个 物品中 选取 填满 容量为 y 的 容器 ,使其 价值最大
子问题之间关联 : 如果当前第 i 件 商品能 容纳 ,则判断是否 容纳 ,如果可以容纳
容纳后的总价值 = 利用容纳后剩余容量的 最大价值 + 第 i 件商品的价值
如果不容纳 ( 容量不够 , 或者容纳后价值 < 不容纳的价值)
不容纳的价值总价值 = 当前容量(x)下 的 能 选取 (i-1)件商品下的最大值
class Solution {
public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 计算01背包问题的结果* @param V int整型 背包的体积* @param n int整型 物品的个数* @param vw int整型vector<vector<>> 第一维度为n,第二维度为2的二维数组,vw[i][0],vw[i][1]分别描述i+1个物品的vi,wi* @return int整型*/int knapsack(int V, int n, vector<vector<int> >& vw) {vector<vector<int>> arr(n,vector<int>(V+1,0));for(int i = 0 ; i < V+1 ; i++){arr[0][i] = (i >= vw[0][0]) ? vw[0][1] : 0; }for(int i = 1 ; i < n;i++){for(int j = 1 ; j < V+1 ;j++){if(vw[i][0] <= j)arr[i][j] = (arr[i-1][j] > arr[i-1][j - vw[i][0]]+vw[i][1]) ? arr[i-1][j] : arr[i-1][j - vw[i][0]]+vw[i][1];else arr[i][j] = arr[i-1][j];}}return arr[n-1][V];// 方法二 : 用 一维数组 --------// 要逆序 因为 要 用的 是 上一行数据 ,如果正序 就会用到每次更新好的 数据vector<int> arr(V+1,0);for(int i = 0 ; i < n;i++){// for(int j = 1 ; j < V+1;j++)for(int j = V ; j > 0;j--){if(vw[i][0] <= j){arr[j] = (arr[j] > arr[j - vw[i][0]] + vw[i][1]) ? arr[j] : arr[j-vw[i][0]] + vw[i][1];}cout << arr[j] << '|';}cout << '-' ;}return arr[V];} }
};
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {for(int i = 2 ; i < cost.size()+1; i++){int tem = (cost[i-1] > cost[i-2]) ? cost[i-2] : cost[i-1];if(i == cost.size())return tem;else cost[i]+=tem;}return 0;}
};
class Solution {
public:bool ispalindrome(string s){for(int left = 0 ,right = s.length()-1;left < right; left++,right--){if(s[left] != s[right])return false;}return true;}// int minCut(string s) {// vector<vector<int>> arr(26, vector<int>(s.length()+1, 0));// int sumtime = 0;// vector<int> dp(s.length()+1, 0);// for (int i = 0; i < s.length(); i++)// {// arr[s[i] - 97][arr[s[i] - 97][0] + 1] = i;// arr[s[i] - 97][0]++;// }// for (int i = 1; i < s.length(); i++)// {// int aim = -1;// dp[i] = i;// for (int aimi = 1;;aimi++)// {// aim = arr[s[i] - 97][aimi];// if(ispalindrome(s.substr(aim,i-aim+1)))// {// if(aim == 0)// {// dp[i] = 0;// break;// }// else // {// dp[i] = (dp[i]> dp[aim-1]+1) ? dp[aim-1]+1 : dp[i];// }// }// if(aim == i)// break;// }// }// return dp[s.length() - 1];// }int minCut(string s) {vector<int>dp (s.length()+1,0);for(int i =1 ;i < s.length();i++){dp[i] = i;for(int j = i;j>=0;j--){if(ispalindrome(s.substr(j,i-j+1))){if(j == 0){dp[i] = 0;break;}dp[i] = (dp[i] < dp[j-1]+1)?dp[i]:dp[j-1]+1;}}}return dp[s.length()-1];}vector<vector<bool>> Premate(string & s){vector<vector<bool>> RT_pre(s.length(),vector<bool>(s.length(),true));for(int i = 0; i < s.length();i++){for(int j = i ;j >= 0;j--){if(i - j == 0)RT_pre[i][j] = true;else if(i - j == 1)RT_pre[i][j] = s[i] == s[j];else RT_pre[i][j] = (s[i] == s[j]) && RT_pre[i-1][j+1];}}return RT_pre;}int minCut(string s) {vector<vector<bool>> RT_pre = Premate(s);vector<int>dp (s.length()+1,0);for(int i =1 ;i < s.length();i++){dp[i] = i;for(int j = i;j>=0;j--){// if(ispalindrome(s.substr(j,i-j+1)))if(RT_pre[i][j]){if(j == 0){dp[i] = 0;break;}dp[i] = (dp[i] < dp[j-1]+1)?dp[i]:dp[j-1]+1;}}}return dp[s.length()-1];}
};
class Solution {
public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.length()+1,vector<int>(word2.length()+1,0));for(int i = 0; i < word2.length()+1;i++)dp[0][i] = i;for(int i = 0; i < word1.length()+1;i++)dp[i][0] = i;for(int i = 1; i < word1.length()+1;i++){for(int j = 1 ;j < word2.length()+1;j++){if(word1[i-1] == word2[j-1])dp[i][j] = dp[i-1][j-1];else dp[i][j] = std::min(std::min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;}} return dp[word1.length()][word2.length()];}
};
class Solution {
public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word1.length()+1,vector<int>(word2.length()+1,0));for(int i = 0; i < word2.length()+1;i++)dp[0][i] = i;for(int i = 0; i < word1.length()+1;i++)dp[i][0] = i;for(int i = 1; i < word1.length()+1;i++){for(int j = 1 ;j < word2.length()+1;j++){if(word1[i-1] == word2[j-1])dp[i][j] = dp[i-1][j-1];else dp[i][j] = std::min(std::min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;}} return dp[word1.length()][word2.length()];}
};
class Solution {
public:int numDistinct(string s, string t) {vector<vector<long long>> dp(t.length(),vector<long long>(s.length()+1,0));for(int i = 1; i < s.length()+1;i++){if(t[0] == s[i-1])dp[0][i] = dp[0][i-1]+1;else dp[0][i] = dp[0][i-1];} for(int i = 1;i < t.length();i++){for(int j = 1 ; j < s.length()+1;j++){if(t[i] == s[j-1]){dp[i][j] = (dp[i-1][j-1]+dp[i][j-1])%1000000007;}else {dp[i][j] = dp[i][j-1];}}}return dp[t.length()-1][s.length()];}
};