赞
踩
伪代码如下:
// 矩阵链乘法,p为矩阵的规模下标数组 Matrix_chain_order(p) n = p.length - 1 // 矩阵的个数 let m and s be new tables, scale is n * n for i = 1 to n // 下标从1开始 m[i,i] = 0 // 单一矩阵无计算代价 for l = 2 to n // length从2到n的矩阵链的计算代价 for i = 1 to n-l+1 // 计算m[i,j]的最小代价 j = i+l-1 // 定义矩阵A(i,j)链 m[i,j] = inf //inf表示无穷 for k = i to j-1 // k为分割点A[i,k] * A[k+1,j] q = m[i,k]+ m[k+1,j]+ p[i]p[k]p[j] if q < m[i,j] m[i, j] = q s[i,j] = k // 记录分割点,进而可以重构解 return m[1, n] and s // m[1,n] 为A[1,n]矩阵链的计算代价, s用于重构解 Get_Optimal_parens(s,i,j) if i == j print "A[i]"; //s[i,i] else print"(" Get_Optimal_parens(s,i,s[i,j]) Get_Optimal_parens(s,s[i,j]+1,j) ")"
C++代码实现如下:
nums_max[i] 为至位置为i处的连续子数组最大值
则[4, -1 2, 1]即为nums_max[6]
nums_max[i] = max{nums_max[i-1], nums[i], nums[i] + nums_max[i-1]} i from 1 to n
最大连续子数组max_arry即为 max(nums_max)
nums_max = [-2, 1, -2, 4, 3, 5, 6, 1, 5];
max_arry = 6
if nums_max[i-1] > 0, nums[i] + nums_max[i-1] 最大
else nums[i] 最大
故 nums_max[i] = nums_max[i-1] > 0 ? nums[i] + nums_max[i-1] : nums[i]
伪代码如下:
int maxSubArry(nums)
len = len(nums)
let nums_max be a n*1 array
nums_max = nums
for x = 1 to len
if nums_max[x-1] > 0
nums_max[x] += nums[x-1]
max_arry = max(nums_max)
return max_arry
C++实现如下
int max_sum = nums[0];
int len = nums.size();
for(int i =1; i< len; ++i)
{
if (nums[i-1]>0) nums[i] += nums[i-1];
max_sum = max(nums[i], max_sum);
}
return max_sum;
string longestPalindrome(string s) { n = len(s) - 1 let p be a len * len matrix; // 初始化一字母,二字母回文 for i = 0 to n p[i][i] = 1 for j = i + 1 to n if s[i] == s[j] p[i][j] = 1 else p[i][j] = 0 // p是一个上三角矩阵,即i < j // 寻找所有三字母回文 for i = 0 to n-2 if s[i] = s[i+2] p[i][i+2] = 1 else P[i][i+2] = 0 // 寻找最长回文字符串 for l = 3 to n for i = 0 to n -l j = i + l; if p[i+1][j-1] and s[i] = s[j] p[i][j] = 1 else p[i][j] = 0 // 存储所有长度字符串的信息 tag = false for l = n downto 1 if !tag for i = 0 to n-l if p[i][i+l] tag = true // 也可以直接在这里return rst = l+1; else break return rst }
string longestPalindrome(string s) { n = len(s) - 1 let p be a len * len matrix; // 初始化一字母,二字母回文 for i = 0 to n p[i][i] = 1 tag = false for j = i + 1 to n if s[i] == s[j] p[i][j] = 1 tag = true else p[i][j] = 0 // p是一个上三角矩阵,即i < j if ! tag return 1 // 寻找所有三字母回文 for i = 0 to n-2 tag = flase if s[i] = s[i+2] p[i][i+2] = 1 tag = true else P[i][i+2] = 0 if !tag return 2 // 寻找最长回文字符串 for l = 3 to n tag = false for i = 0 to n -l j = i + l; if p[i+1][j-1] and s[i] = s[j] p[i][j] = 1 tag = true else p[i][j] = 0 if !tag return l // 该回合没有增加长度 return n + 1 // 循环执行完毕整个字符串均为回文 }
string longestPalindrome(string s) { n = len(s) - 1 let p be a array length is 2n + 1 (2 * len - 1) // 对称点索引值: 0 0.5 1 1.5 ............. n-1 n-0.5 n 对应p[i + j] // 初始化一字母,二字母,三字母回文 p[0]为上一轮循环后回文字符串最大长度,p[2n]为当前字符串最大长度 p[0] = p[2n] = 1 for i = 0 to n-2 if s[i] == s[i+1] p[2i+1] = 2 // 中心点为i与i+1 p[2n] = 2 else p[2i+1] = 1 if s[i] == s[i+2] p[2i+2] = 3 // 中心点为i+1 1 -> n-1 p[2n] = 3 else p[2i+2] = 1 if s[n-1] = s[n] p[2n-1] = 2 if p[2n] == 1 p[2n] = 2 if p[2n] == p[0] // 回文字符串最大长度为 return 1 else p[0] = p[2n] // 更新 // 动态规划 for l = 3 to n // l为长度 for i = 0 to n-l j = i+l if s[i] == s[j] and p[i+j] == l-1 p[i+j] += 2 p[2n] = p[i+j] if p[0] == p[2n] return l return n + 1 }
C++实现代码如下
需要知识:
int climbStairs(int n) {
if(n==1)
return 1;
else if(n == 2)
return 2;
else
{
vector<int> p;
p.push_back(1); p.push_back(2);
for(int i=2; i< n; ++i)
{
p.push_back(p[i-1] + p[i-2]);
}
return p[n-1];
}
int maxProfit(vector<int>& prices) { int len = prices.size(); vector<int> prices_sub = prices; if (len <= 1) return 0; for(int i =1; i< len; ++i) { prices_sub[i] -= prices[i-1]; } prices_sub[0] = 0; for(int i=1; i< len; ++i) { if (prices_sub[i-1] >= 0) { prices_sub[i] += prices_sub[i-1]; } prices_sub[0] = max(prices_sub[0], prices_sub[i]); } return prices_sub[0]; }
int rob(vector<int>& nums) { vector<int> price = nums; int len = nums.size(); if(len==0) return 0; else if(len == 1) return nums[0]; else if(len == 2) return max(nums[0],nums[1]); else { price[1] = max(price[0],price[1]); for(int i=2; i<len; ++i) { price[i] = max(price[i] + price[i-2], price[i-1]); } } return price[len-1]; }
int minCost(vector<vector<int>>& costs) { int len = costs.size(); // 有多少个房子 if(len == 0) return 0; else if(len == 1) { int rst = costs[0][0]; rst = min(rst,min(costs[0][1],costs[0][2])); return rst; } else { vector<vector<int>> prices = costs; prices[0][0] = min(costs[0][1], costs[0][2]); prices[0][1] = min(costs[0][0], costs[0][2]); prices[0][2] = min(costs[0][0], costs[0][1]); for(int i=1; i<len; ++i) { prices[i][0] = min(prices[i-1][1] + costs[i][1], prices[i-1][2]+ costs[i][2]); prices[i][1] = min(prices[i-1][0] + costs[i][0], prices[i-1][2]+ costs[i][2]); prices[i][2] = min(prices[i-1][0] + costs[i][0], prices[i-1][1]+ costs[i][1]); } int n =len-1; int rst = min(prices[n][0],min(prices[n][1], prices[n][2])); return rst; } }
int numWays(int n, int k) { if(n == 0 or k == 0) return 0; if(n==1) return k; if(n==2) return k*(k-1) + k; else { vector<int> ways; int mulp = k-1; ways.push_back(k); // 第一次涂一次一种颜色有k种涂色方案 ways.push_back(k + k*mulp); // 第一次连续涂两次同种颜色有k种涂色方案 + 涂两种不同颜色 for(int i=2; i<n; ++i) { ways.push_back(mulp*ways[i-1] + mulp*ways[i-2]); } return ways[n-1]; } }
python代码如下
def __init__(self, nums: List[int]):
length = len(nums);
if length == 0:
return None
else:
self.nums = nums;
for x_cur in range(length):
if x_cur > 0:
nums[x_cur] += nums[x_cur - 1] # 求前n项和
def sumRange(self, i: int, j: int) -> int:
if i>0:
return self.nums[j] - self.nums[i-1]
else:
return self.nums[j]
bool isSubsequence(string s, string t) {
int i_cur = 0;
int j_cur = 0;
int len = s.size();
int len_t = t.size();
while(j_cur < len_t)
{
if(s[i_cur] == t[j_cur])
++ i_cur;
++j_cur;
if(i_cur == len) return true;
}
return false;
}
注意题目的描述t很长但均为英文小写字母
int minCostClimbingStairs(vector<int>& cost) {
int len = cost.size();
cost.push_back(0);
if(len == 2)
return cost[1];
else
{
for(int i=2; i<=len; ++i)
cost[i] = min(cost[i] + cost[i-1], cost[i] + cost[i-2]);
return cost[len];
}
}
class Solution {
public:
bool divisorGame(int N) {
if(N%2 == 0)
return true;
else return false;
}
};
hhhhh 是不是很奇怪但结果恰恰是正确的
那么接下来给出C++的动态规划思想和实现方法
再看看能不能用数学方法证明
首先我们知道N = 1时 谁先喊谁就输了,因为N没有在1和N之间的公约数
那我们在考虑N=2时 2 = 1 * 2 故只能喊X= 1那么N-X = 1 由N = 1 我们可以知道谁喊谁就输了
我们定义数组nums[length]
int minPathSum(vector<vector<int>>& grid) { int m = grid.size(); // col int n = grid[0].size(); // row int rst = 0; if(m==0||n==0); else if(m==1||n==1) { if(n==1) for(int i=0; i<m; ++i) rst += grid[i][0]; else for(int i=0; i<n; ++i) rst += grid[0][i]; } else { for(int i=1; i<n; ++i) { grid[0][i] += grid[0][i-1]; } for(int i=1; i<m; ++i) { grid[i][0] += grid[i-1][0]; } // 边界初始化 for(int i=1; i<m; ++i) { for(int j=1; j<n; ++j) grid[i][j] += min(grid[i-1][j], grid[i][j-1]); } for(int i=0; i<m; ++i) { for(int j=0; j<n; ++j) cout << grid[i][j] << endl; } rst = grid[m-1][n-1]; } return rst; }
int maxProfit(vector<int>& prices) { int len = prices.size(); int rst = 0; if(len > 1) { vector<vector<int>> w; for(int i=0; i<len; ++i) { vector<int> temp = {0}; // 生成临时容器第一个数据存储0 int j=i; int k=i; ++j; // 指针k为指针j的前一个指针 for(int cur = 0; j<len; ++j,++k,++cur) { int sub = prices[j] - prices[k]; //与前一个数的差值 if(temp[cur] < 0) temp.push_back(sub); else temp.push_back(sub + temp[cur]); } w.push_back(temp); } for(int i = 0; i<len; ++i) { int max_now_circle = w[i][0]; for(int j=1; j<w[i].size(); ++j) { max_now_circle = w[i][j] = max(max_now_circle, w[i][j]); //存储差值 } }// A[i.j]的单一连续数组的最大值 for(int l = 4; l<len; ++l) // 以l作为区分问题的参量 { int j= l; for(int i=0; j<w[i].size(); ++i) // w为上三角矩阵要特别注意索引(i表示pricesA[i,j],j表示距离i的距离) { int max_now_circle = w[i][j]; int pre_len = 1; int mid_tail=i+3; int tail_len = l-3;// 分割点 for(; tail_len>0; ++pre_len, ++mid_tail, --tail_len) max_now_circle = max(max_now_circle, w[i][pre_len]+w[mid_tail][tail_len]); w[i][j] = max_now_circle; } } rst = w[0][len-1]; } return rst; }
int maxProfit(vector<int>& prices) { int dp[5] = {0,0,0,0,0}; int len = prices.size(); int rst = 0; if(len >1) { dp[1] -= prices[0]; dp[3] = -99999999; for(int i=1; i<len; ++i) { dp[0] = 0; dp[1] = max(dp[1], dp[0] - prices[i]); // 第一次买入 dp[2] = max(dp[2], dp[1] + prices[i]); // 第一次卖出 dp[3] = max(dp[3], dp[2] - prices[i]); // 第二次买入 dp[4] = max(dp[4], dp[3] + prices[i]); // 第二次卖出 } rst = max(dp[2],dp[4]); } return rst; }
在这里插入代码片
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。