[Algo] 一维动态规划
fx1 - 暴力递归, fx2 - 自顶向底动态规划(记忆化搜索), fx3 - 自底向顶动态规划(严格位置依赖)
1. 最低票价
// 1. 最低票价
// https://leetcode.cn/problems/minimum-cost-for-tickets/description/
int duration[3] = {1, 7, 30};
int f11(vector<int>& days, vector<int>& costs, int i){
if (i == days.size()) return 0;
int ans = INT32_MAX;
for (int k = 0, j = i; k < 3; k++)
{
while (j < days.size() && days[j] < days[i] + duration[k]) j++;
ans = min(ans, costs[k] + f11(days, costs, j));
}
return ans;
}
int f12(vector<int>& days, vector<int>& costs, int i, vector<int>& mem)
{
if (i == days.size()) return 0;
if (mem[i] != -1) return mem[i];
int ans = INT32_MAX;
for (int k = 0, j = i; k < 3; k++)
{
while (j < days.size() && days[j] < days[i] + duration[k]) j++;
ans = min(ans, costs[k] + f12(days, costs, j, mem));
}
mem[i] = ans;
return ans;
}
int f13(vector<int>& days, vector<int>& costs, vector<int>& dp)
{
dp[dp.size() - 1] = 0;
for (int i = days.size() - 1; i >= 0; i--)
for (int k = 0, j = i; k < 3; k++)
{
while (j < days.size() && days[j] < days[i] + duration[k]) j++;
dp[i] = min(dp[i], costs[k] + dp[j]);
}
return dp[0];
}
int mincostTickets(vector<int>& days, vector<int>& costs) {
vector<int> dp(days.size() + 1, INT32_MAX);
return f13(days, costs, dp);
}
2. 解码方法
// 2. 解码方法
// https://leetcode.cn/problems/decode-ways/
int f21(string &s, int i)
{
if (i == s.length()) return 1;
if (s[i] == '0') return 0;
if (i + 1 < s.length() && (s[i] - '0') * 10 + s[i + 1] - '0' <= 26) return f21(s, i + 1) + f21(s, i + 2);
else return f21(s, i + 1);
}
int f22(string &s, int i, vector<int> &mem)
{
if (i == s.length()) return 1;
if (mem[i] != -1) return mem[i];
int ans;
if (s[i] == '0') ans = 0;
else ans = f22(s, i + 1, mem);
if (s[i] != '0' && i + 1 < s.length() && (s[i] - '0') * 10 + s[i + 1] - '0' <= 26) ans += f22(s, i + 2, mem);
mem[i] = ans;
return ans;
}
int f23(string &s, vector<int> &dp)
{
dp[dp.size() - 1] = 1;
for (int i = s.size() - 1; i >= 0; i--)
{
if (s[i] == '0') dp[i] = 0;
else dp[i] = dp[i + 1];
if (s[i] != '0' && i + 1 < s.length() && (s[i] - '0') * 10 + s[i + 1] - '0' <= 26) dp[i] += dp[i + 2];
}
return dp[0];
}
int numDecodings(string s) {
vector<int> dp(s.length() + 1);
return f23(s, dp);
}
3. 最长有效括号串
// 3. 最长有效括号串
// https://leetcode.cn/problems/longest-valid-parentheses/description/
int longestValidParentheses(string s) {
vector<int> dp(s.length());
for (int i = 1; i < s.length(); i++)
{
if (s[i] == ')')
{
int p = i - dp[i - 1] - 1;
if (p >= 0 && s[p] == '(') dp[i] = dp[i - 1] + 2 + (p - 1 >= 0 ? dp[p - 1] : 0);
}
}
int ans = 0;
for (int len : dp) ans = max(ans, len);
return ans;
}
标签:return,int,days,vector,一维,ans,动态,规划,dp
From: https://www.cnblogs.com/yaoguyuan/p/18658023