treeman667
some guy stole my name 😡
dp intro
1D dp/application
Edit Distance/application
Knapsack
2D DP
Range dp
Bitmask dp
digit dp
dp on broken profiles
int fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n-1) + fib(n-2);
}
int fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return fib(n-1) + fib(n-2);
}
fib(n)
fib(n-1)
fib(n-2)
fib(n-2)
fib(n-3)
fib(n-3)
fib(n-4)
fib(n)
fib(n-1)
fib(n-2)
fib(n-2)
fib(n-3)
fib(n-3)
fib(n-4)
遞迴中,會計算許多重複的值 (如: fib(n-2), fib(n-3) )
這會降低程式效率 😨😨😨
有沒有辦法只計算一次?
fib(n)
fib(n-1)
fib(n-2)
fib(n-2)
fib(n-3)
fib(n-3)
fib(n-4)
遞迴中,會計算許多重複的值 (如: fib(n-2), fib(n-3) )
這會降低程式效率 😨😨😨
有沒有辦法只計算一次?
我們可以利用 DP
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 114514 + 1919810 + 1234 + 67;
ll m[MAXN];
ll fib(int n)
{
if (n == 0)
return 0;
if (n == 1)
return 1;
return m[n] = (m[n]? m[n] : fib(n-1) + fib(n-2));
}
int main()
{
int n;
cin >> n;
cout << fib(n);
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
long long saves[1000002];
signed main()
{
int n;
cin >> n;
saves[0] = 1;
for (int i=0; i <= n; i++)
{
for (int j=1; j <= 6; j++)
if (i - j >= 0) saves[i] += saves[i-j];
if (saves[i] >= (1e9 + 7)) saves[i] %= 1000000007;
}
cout << saves[n];
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
const int INF = 1919810 + 114514 + 1234 + 67;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
vector<int> dp(n+10, INF);
vector<int> saves(n+10);
for (int i=1; i <= n; i++)
cin >> saves[i];
dp[1] = 0;
for (int i=1; i <= n; i++)
{
if (i + 1 <= n) dp[i+1] = min(dp[i+1], dp[i] + abs(saves[i] - saves[i+1]));
if (i + 2 <= n) dp[i+2] = min(dp[i+2], dp[i] + abs(saves[i] - saves[i+2]));
}
cout << dp[n];
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
vector<array<int, 3>> dp(n+1);
for (int i = 1; i <= n; i++)
{
int a, b, c;
cin >> a >> b >> c;
dp[i][0] = max(dp[i-1][1] + a, dp[i-1][2] + a);
dp[i][1] = max(dp[i-1][0] + b, dp[i-1][2] + b);
dp[i][2] = max(dp[i-1][0] + c, dp[i-1][1] + c);
}
cout << max({dp[n][0], dp[n][1], dp[n][2]});
}
# PRESENTING CODE
| 😡 | M | O | V | I | E | |
| L | ||||||
| O | ||||||
| V | ||||||
| E |
| 😡 | M | O | V | I | E | |
| L | ||||||
| O | ||||||
| V | ||||||
| E |
| 😡 | M | O | V | I | E | |
| 0 | 1 | 2 | 3 | 4 | 5 | |
| L | 1 | 1 | 2 | 3 | 4 | 5 |
| O | 2 | 2 | 1 | 2 | 3 | 4 |
| V | 3 | 3 | 2 | 1 | 2 | 2 |
| E | 4 | 4 | 3 | 2 | 2 | 2 |
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1, s2; cin >> s1 >> s2;
int n = s1.length(), m = s2.length();
vector<vector<int>> dp(n+1, vector<int>(m+1));
for (int i=0; i <= n; i++) dp[i][0] = i;
for (int j=1; j <= m; j++) dp[0][j] = j;
for (int i=1; i <= n; i++)
{
for (int j=1; j <= m; j++)
{
if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1];
else dp[i][j] = min({dp[i-1][j], dp[i][j-1], dp[i-1][j-1]}) + 1;
}
}
cout << dp[n][m];
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
int main()
{
cin.tie(nullptr)->ios::sync_with_stdio(false);
int n, m; cin >> n >> m;
vector<int> arr1(n), arr2(m);
for (auto &x : arr1) cin >> x; for (auto &x : arr2) cin >> x;
vector<vector<int>> dp(n+1, vector<int>(m+1));
for (int i=1; i <= n; i++)
{
for (int j=1; j <= m; j++)
{
if (arr1[i-1] == arr2[j-1]) dp[i][j] = dp[i-1][j-1] + 1;
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
int &ans = dp[n][m];
cout << ans << std::endl;
int i = n, j = m; vector<int> res;
while (ans != 0)
{
if (arr1[i-1] == arr2[j-1]) {res.push_back(arr1[i-1]); i--; j--; ans--;}
else if(dp[i][j-1] > dp[i-1][j]) j--;
else i--;
}
reverse(res.begin(), res.end()); for (auto &x : res) cout << x << ' ';
}
# PRESENTING CODE
| 0 | |||||
| 0 | |||||
| 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | |||||
| 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | ||||
| 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | |||
| 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 | 0 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 | 0 | 5 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 | 0 | 5 | 7 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 | 0 | 5 | 7 | 7 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 5 | 5 | 5 | 5 |
| 0 | 0 | 5 | 7 | 7 | 12 |
物品A
價值: 5
重量: 2
物品B
價值: 7
重量: 3
#include <bits/stdc++.h>
using namespace std;
int main() {
int books, max_weight;
cin >> books >> max_weight;
vector<pair<int, int>> book_info(books);
for (auto& book : book_info) cin >> book.first;
for (auto& book : book_info) cin >> book.second;
vector <vector <int>> dp(books+1, vector <int>(max_weight + 1, 0));
for (int i=1; i <= books; i++) {
int price = book_info[i-1].first;
int page = book_info[i-1].second;
for (int j=0; j <= max_weight; j++)
if (j >= price) dp[i][j] = max(dp[i-1][j], dp[i-1][j-price] + page);
else dp[i][j] = dp[i-1][j];
}
cout << dp.back().back();
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n, x;
cin >> n >> x;
int dp[x+1];
memset(dp, 0, sizeof(dp));
vector<array<int, 2>> saves(n);
for (int i=0; i < n; i++)
cin >> saves[i][0];
for (int i=0; i < n; i++)
cin >> saves[i][1];
for (int i=0; i < n; i++)
for (int j=x; j >= saves[i][0]; j--)
dp[j] = max(dp[j], dp[j - saves[i][0]] + saves[i][1]);
cout << dp[x];
}
# PRESENTING CODE
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 401;
ll dp[MAXN][MAXN];
ll saves[MAXN][MAXN];
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
memset(dp, 0x3f, sizeof(dp));
int n;
cin >> n;
for (int i=1; i <= n; i++)
cin >> saves[i][i], dp[i][i] = 0;
for (int i=1; i <= n; i++)
for (int j=i+1; j <= n; j++)
saves[i][j] = saves[i][j-1] + saves[j][j];
for (int l=1; l < n; l++)
for (int i=1, j = i + l; j <= n ; i++, j++)
for (int k=i; k < j; k++)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + saves[i][j]);
cout << dp[1][n];
}
# PRESENTING CODE
By treeman667