λμ κ³νλ²(Dynamic Programming)
볡μ‘ν λ¬Έμ λ₯Ό κ°λ¨ν μ¬λ¬ κ°μ λ¬Έμ λ‘ λλμ΄ νΈλ λ°©λ²μ΄λ€.
- λκ°μ μ°μ°μ λ°λ³΅νμ§ μλλ‘ λ§λ€μ΄ μ£Όκ³ μ€ν μκ°μ μ€μΌ μ μλ€.
- μμ λ¬Έμ λ€μ νμ΄λκ°λ€ 보면 μ΄μ μ ꡬν΄λ λ μμ λ¬Έμ λ€μ΄ νμ©λλ κ²μ νμΈνκ² λλ€. μ΄μ λν κ·μΉμ μ°Ύμμ λ μ νμμ λμΆν΄ λ΄μ΄ λμ κ³νλ²μ μ μ©νλ€.
νμ΄λ²
- dp[i]κ° μλ―Ένλ λ°
- dp[i]λ₯Ό initialize νλ λ°©λ²
- dp[i]μ μ νμ
- dp[i]λ₯Ό μ±μ°λ μμ
- μ λ΅μ΄ μλ―Ένλ λ°
Leetcode: Word Break
Word Break I Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. Note: The same word in the dictionary may be reused mul
jyeonth.tistory.com
λ¬Έμ
https://www.acmicpc.net/problem/1932
1932λ²: μ μ μΌκ°ν
λ¬Έμ 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 μ κ·Έλ¦Όμ ν¬κΈ°κ° 5μΈ μ μ μΌκ°νμ ν λͺ¨μ΅μ΄λ€. 맨 μμΈ΅ 7λΆν° μμν΄μ μλμ μλ μ μ€ νλλ₯Ό μ ννμ¬ μλμΈ΅μΌλ‘ λ΄λ €μ¬ λ, μ΄μ κΉμ§ μ νλ μμ ν©μ΄ μ΅οΏ½
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[501][501];
int main()
{
int n;
cin >> n;
int result = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= i; j++) {
cin >> dp[i][j];
if (j == 1) // μΌμͺ½ λκ°μ
dp[i][j] += dp[i - 1][j];
else if (i == j) // μ€λ₯Έμͺ½ λκ°μ
dp[i][j] += dp[i - 1][j - 1];
else
dp[i][j] += max(dp[i - 1][j], dp[i - 1][j - 1]);
if (result < dp[i][j])
result = dp[i][j];
}
cout << result;
}
https://www.acmicpc.net/problem/1463
1463λ²: 1λ‘ λ§λ€κΈ°
첫째 μ€μ 1λ³΄λ€ ν¬κ±°λ κ°κ³ , 106λ³΄λ€ μκ±°λ κ°μ μ μ Nμ΄ μ£Όμ΄μ§λ€.
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[1000001];
int main()
{
int n;
cin >> n;
dp[1] = 0;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + 1;
if (i % 2 == 0 && dp[i / 2] + 1 <= dp[i])
dp[i] = dp[i / 2] + 1;
if (i % 3 == 0 && dp[i / 3] + 1 <= dp[i])
dp[i] = dp[i / 3] + 1;
}
cout << dp[n];
}
https://www.acmicpc.net/problem/1912
1912λ²: μ°μν©
첫째 μ€μ μ μ n(1 ≤ n ≤ 100,000)μ΄ μ£Όμ΄μ§κ³ λμ§Έ μ€μλ nκ°μ μ μλ‘ μ΄λ£¨μ΄μ§ μμ΄μ΄ μ£Όμ΄μ§λ€. μλ -1,000λ³΄λ€ ν¬κ±°λ κ°κ³ , 1,000λ³΄λ€ μκ±°λ κ°μ μ μμ΄λ€.
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[100001];
int main()
{
int n;
cin >> n >> dp[0];
for (int i = 1; i < n; ++i) {
cin >> dp[i];
dp[i] = max(dp[i], dp[i - 1] + dp[i]);
}
cout << *max_element(dp, dp + n);
}
https://leetcode.com/problems/longest-valid-parentheses/
Longest Valid Parentheses - LeetCode
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
#include <vector>
#include <string>
#include <stack>
using namespace std;
class Solution {
public:
int longestValidParentheses(string s) {
int answer = 0;
stack<int> st;
vector<int> dp(s.size(), 0);
for (int i = 0; i < s.size(); i++) {
char c = s[i];
if (c == '(')
st.push(i);
else {
if (st.empty())
continue;
int index = st.top();
st.pop();
dp[i] = i - index + 1 + (index > 0 ? dp[index - 1] : 0);
}
answer = max(answer, dp[i]);
}
return answer;
}
};
λ¬Έμ : μ°μ κ°μ΄ λΆκ°λ₯ν λ μ΅λκ° κ΅¬νκΈ°
https://www.acmicpc.net/problem/2579
2579λ²: κ³λ¨ μ€λ₯΄κΈ°
κ³λ¨ μ€λ₯΄κΈ° κ²μμ κ³λ¨ μλ μμμ λΆν° κ³λ¨ κΌλκΈ°μ μμΉν λμ°©μ κΉμ§ κ°λ κ²μμ΄λ€. <κ·Έλ¦Ό 1>κ³Ό κ°μ΄ κ°κ°μ κ³λ¨μλ μΌμ ν μ μκ° μ°μ¬ μλλ° κ³λ¨μ λ°μΌλ©΄ κ·Έ κ³λ¨μ μ°μ¬ μλ μ
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int stair[300], dp[300];
for (int i = 0; i < n; i++)
cin >> stair[i];
dp[0] = stair[0];
dp[1] = stair[0] + stair[1];
dp[2] = max(stair[1] + stair[2], stair[0] + stair[2]);
for (int i = 3; i < n; i++)
dp[i] = max(stair[i] + dp[i - 2], stair[i] + stair[i - 1] + dp[i - 3]);
cout << dp[n - 1];
}
https://www.acmicpc.net/problem/2156
2156λ²: ν¬λμ£Ό μμ
ν¨μ£Όλ ν¬λμ£Ό μμνμ κ°λ€. κ·Έ κ³³μ κ°λλ, ν μ΄λΈ μμ λ€μν ν¬λμ£Όκ° λ€μ΄μλ ν¬λμ£Ό μμ΄ μΌλ ¬λ‘ λμ¬ μμλ€. ν¨μ£Όλ ν¬λμ£Ό μμμ νλ €κ³ νλλ°, μ¬κΈ°μλ λ€μκ³Ό κ°μ λ κ°μ§ κ·
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int grape[10001];
for (int i = 1; i <= n; ++i)
cin >> grape[i];
int dp[10001]{};
dp[1] = grape[1];
dp[2] = grape[1] + grape[2];
for (int i = 3; i <= n; ++i)
dp[i] = max(dp[i - 1], max(dp[i - 2], dp[i - 3] + grape[i - 1]) + grape[i]);
cout << dp[n];
}
λ¬Έμ : LIS(μ΅μ₯ μ¦κ° λΆλΆ μμ΄)
https://www.acmicpc.net/problem/11053
11053λ²: κ°μ₯ κΈ΄ μ¦κ°νλ λΆλΆ μμ΄
μμ΄ Aκ° μ£Όμ΄μ‘μ λ, κ°μ₯ κΈ΄ μ¦κ°νλ λΆλΆ μμ΄μ ꡬνλ νλ‘κ·Έλ¨μ μμ±νμμ€. μλ₯Ό λ€μ΄, μμ΄ A = {10, 20, 10, 30, 20, 50} μΈ κ²½μ°μ κ°μ₯ κΈ΄ μ¦κ°νλ λΆλΆ μμ΄μ A = {10, 20, 10, 30, 20, 50} μ΄
www.acmicpc.net
#include <iostream>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, ans = 0;
cin >> N;
int A[1010]{}, dp[1010]{};
for (int i = 1; i <= N; i++)
cin >> A[i];
for (int i = 1; i <= N; i++) {
for (int j = 1; j < i; j++)
if (A[i] > A[j] && dp[i] < dp[j])
dp[i] = dp[j];
dp[i]++;
if (ans < dp[i])
ans = dp[i];
}
cout << ans;
}
https://www.acmicpc.net/problem/2565
2565λ²: μ κΉμ€
첫째 μ€μλ λ μ λ΄λ μ¬μ΄μ μ κΉμ€μ κ°μκ° μ£Όμ΄μ§λ€. μ κΉμ€μ κ°μλ 100 μ΄νμ μμ°μμ΄λ€. λμ§Έ μ€λΆν° ν μ€μ νλμ© μ κΉμ€μ΄ Aμ λ΄λμ μ°κ²°λλ μμΉμ λ²νΈμ Bμ λ΄λμ μ°κ²°λλ
www.acmicpc.net
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int N;
cin >> N;
vector<pair<int, int>> poles;
int dp[100];
for (int i = 0; i < N; i++) {
int a, b;
cin >> a >> b;
poles.push_back({ a, b });
dp[i] = 1;
}
// a μ λ΄λμ μ κΉμ€ μμΉλ₯Ό κΈ°μ€μΌλ‘ μ λ ¬
sort(poles.begin(), poles.end());
// a μ λ΄λλ₯Ό κΈ°μ€μΌλ‘ μ κΉμ€μ μ λ ¬νμ λ
// b μ λ΄λλ μ κΉμ€ μμκ° μ λ ¬λμ΄μμ΄μΌ λμ΄ μν€μ§ μλλ€.
for (int i = 0; i < N; i++)
for (int j = 0; j < i; j++)
if (poles[i].second > poles[j].second)
dp[i] = max(dp[i], dp[j] + 1);
// b μ λ΄λμ λΆλΆμ¦κ°μμ΄μ λͺ¨λ μ λ ¬λ μνμ΄λ―λ‘
// μλ κΈΈμ΄μμ λΆλΆμ¦κ°μμ΄μ κΈΈμ΄λ₯Ό λΊλ€.
cout << N - *max_element(dp, dp + N);
}
λ¬Έμ : LCS(μ΅μ₯ κ³΅ν΅ λΆλΆ μμ΄)
https://www.acmicpc.net/problem/9251
9251λ²: LCS
LCS(Longest Common Subsequence, μ΅μ₯ κ³΅ν΅ λΆλΆ μμ΄)λ¬Έμ λ λ μμ΄μ΄ μ£Όμ΄μ‘μ λ, λͺ¨λμ λΆλΆ μμ΄μ΄ λλ μμ΄ μ€ κ°μ₯ κΈ΄ κ²μ μ°Ύλ λ¬Έμ μ΄λ€. μλ₯Ό λ€μ΄, ACAYKPμ CAPCAKμ LCSλ ACAKκ° λλ€.
www.acmicpc.net
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int dp[1001][1001];
int main()
{
string s1, s2;
cin >> s1 >> s2;
for (int i = 1; i <= s1.length(); i++)
for (int j = 1; j <= s2.length(); j++)
dp[i][j] = (s1[i - 1] == s2[j - 1]) ? dp[i - 1][j - 1] + 1 : max(dp[i][j - 1], dp[i - 1][j]);
cout << dp[s1.length()][s2.length()];
}
λ¬Έμ : λ μ
μ£Όμ΄μ§ μ©λμ μ΄κ³Όνμ§ μμΌλ©΄μ μ 체 μ΄λμ΄ μ΅λκ° λ μ μλλ‘ νλ λ¬Έμ μ΄λ€.
https://www.acmicpc.net/problem/12865
12865λ²: νλ²ν λ°°λ
첫 μ€μ λ¬Όνμ μ N(1 ≤ N ≤ 100)κ³Ό μ€μκ° λ²νΈ μ μλ λ¬΄κ² K(1 ≤ K ≤ 100,000)κ° μ£Όμ΄μ§λ€. λ λ²μ§Έ μ€λΆν° Nκ°μ μ€μ κ±°μ³ κ° λ¬Όκ±΄μ λ¬΄κ² W(1 ≤ W ≤ 100,000)μ ν΄λΉ 물건μ κ°μΉ V(0 ≤ V ≤ 1,000)
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[100001];
int main()
{
int n, k;
cin >> n >> k;
while (n--) {
int w, v;
cin >> w >> v;
for (int i = 0; i <= k - w; i++)
dp[i] = max(dp[i], dp[i + w] + v);
}
cout << *max_element(dp, dp + k);
}
https://www.acmicpc.net/problem/2293
2293λ²: λμ 1
첫째 μ€μ n, kκ° μ£Όμ΄μ§λ€. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) λ€μ nκ°μ μ€μλ κ°κ°μ λμ μ κ°μΉκ° μ£Όμ΄μ§λ€. λμ μ κ°μΉλ 100,000λ³΄λ€ μκ±°λ κ°μ μμ°μμ΄λ€.
www.acmicpc.net
#include <iostream>
using namespace std;
int main()
{
int n, k;
cin >> n >> k;
int dp[10001]{ 1 };
for (int i = 0; i < n; i++) {
int tmp;
cin >> tmp;
for (int j = tmp; j <= k; j++)
dp[j] += dp[j - tmp];
}
cout << dp[k];
}
https://www.acmicpc.net/problem/11052
11052λ²: μΉ΄λ ꡬ맀νκΈ°
첫째 μ€μ λ―Όκ·κ° ꡬ맀νλ €κ³ νλ μΉ΄λμ κ°μ Nμ΄ μ£Όμ΄μ§λ€. (1 ≤ N ≤ 1,000) λμ§Έ μ€μλ Piκ° P1λΆν° PNκΉμ§ μμλλ‘ μ£Όμ΄μ§λ€. (1 ≤ Pi ≤ 10,000)
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N;
cin >> N;
int card[1001], dp[1001]{};
for (int i = 1; i <= N; ++i)
cin >> card[i];
for (int i = 1; i <= N; i++)
for (int j = 1; j <= i; j++)
dp[i] = max(dp[i], dp[i - j] + card[j]);
cout << dp[N];
}
λ¬Έμ : μ΅μλΉμ© ꡬνκΈ°
https://www.acmicpc.net/problem/11066
11066λ²: νμΌ ν©μΉκΈ°
λ¬Έμ μμ€κ°μΈ κΉλμ μ μμ€μ μ¬λ¬ μ₯(chapter)μΌλ‘ λλμ΄ μ°λλ°, κ° μ₯μ κ°κ° λ€λ₯Έ νμΌμ μ μ₯νκ³€ νλ€. μμ€μ λͺ¨λ μ₯μ μ°κ³ λμλ κ° μ₯μ΄ μ°μ¬μ§ νμΌμ ν©μ³μ μ΅μ’ μ μΌλ‘ μμ€μ οΏ½οΏ½
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[501][501];
int sum[501];
int main()
{
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> sum[i];
sum[i] += sum[i - 1];
}
for (int i = 1; i <= n; ++i)
for (int start = 1; start + i <= n; ++start) {
int end = start + i;
dp[start][end] = 1e9;
for (int j = start; j < end; ++j)
dp[start][end] = min(dp[start][end], dp[start][j] + dp[j + 1][end] + sum[end] - sum[start - 1]);
}
cout << dp[1][n] << endl;
}
}
https://www.acmicpc.net/problem/11049
11049λ²: νλ ¬ κ³±μ μμ
첫째 μ€μ μ λ ₯μΌλ‘ μ£Όμ΄μ§ νλ ¬μ κ³±νλλ° νμν κ³±μ μ°μ°μ μ΅μκ°μ μΆλ ₯νλ€. μ λ΅μ 231-1 λ³΄λ€ μκ±°λ κ°μ μμ°μμ΄λ€. λν, μ΅μ μ μμλ‘ μ°μ°ν΄λ μ°μ° νμκ° 231-1λ³΄λ€ μκ±°λ κ°οΏ½
www.acmicpc.net
#include <iostream>
#include <algorithm>
using namespace std;
int dp[501][501];
int a[501][2];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i][0] >> a[i][1];
if (i > 1)
dp[i - 1][i] = a[i - 1][0] * a[i - 1][1] * a[i][1];
}
for (int i = 2; i <= n; i++) // νλ ¬μ΄ 3κ° μ΄μμΌ κ²½μ°
for (int start = 1; start + i <= n; start++) {
int end = start + i;
dp[start][end] = 1e9;
for (int j = start; j < end; j++)
dp[start][end] = min(dp[start][end], dp[start][j] + dp[j + 1][end] + a[start][0] * a[j][1] * a[end][1]);
}
cout << dp[1][n];
}
https://leetcode.com/problems/dungeon-game/
#include <vector>
#include <math.h>
using namespace std;
class Solution
{
public:
int dp[201][201]{};
int calculateMinimumHP(vector<vector<int>>& dungeon)
{
int m = dungeon.size();
int n = dungeon[0].size();
for (int i = m - 1; i >= 0; --i) {
for (int j = n - 1; j >= 0; --j) {
if (i == m - 1 && j == n - 1)
dp[i][j] = max(1, 1 - dungeon[i][j]);
else if (i == m - 1)
dp[i][j] = max(1, dp[i][j + 1] - dungeon[i][j]);
else if (j == n - 1)
dp[i][j] = max(1, dp[i + 1][j] - dungeon[i][j]);
else
dp[i][j] = max(1, min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]);
}
}
return dp[0][0];
}
};
λ¬Έμ : DFS+DP
https://www.acmicpc.net/problem/1520
1520λ²: λ΄λ¦¬λ§ κΈΈ
μ¬νμ λ λ μΈμ€μ΄λ μ§λλ₯Ό νλ ꡬνμλ€. μ΄ μ§λλ μλ κ·Έλ¦Όκ³Ό κ°μ΄ μ§μ¬κ°ν λͺ¨μμ΄λ©° μ¬λ¬ μΉΈμΌλ‘ λλμ΄μ Έ μλ€. ν μΉΈμ ν μ§μ μ λνλ΄λλ° κ° μΉΈμλ κ·Έ μ§μ μ λμ΄κ° μ°μ¬ μμΌοΏ½
www.acmicpc.net
#include <iostream>
using namespace std;
int M, N;
int h[500][500], dp[500][500];
int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
int f(int y, int x, int hei)
{
if (x < 0 || x >= N || y < 0 || y >= M || h[y][x] >= hei)
return 0;
else if (y == M - 1 && x == N - 1)
return 1;
else if (dp[y][x] >= 0)
return dp[y][x];
dp[y][x] = 0;
for (int i = 0; i < 4; i++)
dp[y][x] += f(y + dir[i][0], x + dir[i][1], h[y][x]);
return dp[y][x];
}
int main()
{
cin >> M >> N;
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++) {
cin >> h[i][j];
dp[i][j] = -1;
}
cout << f(0, 0, h[0][0] + 1);
}
λ¬Έμ : DFS+BFS+DP
https://leetcode.com/problems/word-ladder-ii/
Word Ladder II - LeetCode
Can you solve this real interview question? Word Ladder II - A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that: * Every adjacent pair of words diffe
leetcode.com
#include <vector>
#include <map>
#include <queue>
#include <string>
using namespace std;
class Solution {
public:
vector<vector<string>> answers;
vector<string> answer;
bool check[500];
map<string, int> counts;
int minCount;
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
minCount = 0;
queue<pair<string, int>> q;
q.push({ beginWord, 0 });
while (!q.empty()) {
string word = q.front().first;
int cnt = q.front().second;
q.pop();
if (word == endWord) {
minCount = cnt;
break;
}
for (int i = 0; i < wordList.size(); i++)
{
if (check[i] || isNearWord(word, wordList[i]) == false)
continue;
check[i] = true;
q.push({ wordList[i], cnt + 1 });
}
}
memset(check, false, sizeof(check));
answer.push_back(beginWord);
dfs(beginWord, endWord, wordList, 0);
return answers;
}
bool dfs(string& curWord, string& endWord, vector<string>& wordList, int count) {
if (count == minCount) {
if (curWord != endWord)
return false;
else {
answers.push_back(answer);
return true;
}
}
else if (counts.find(curWord) != counts.end() && counts[curWord] <= count)
return false;
bool movable = false;
for (int i = 0; i < wordList.size(); i++) {
if (check[i] || isNearWord(curWord, wordList[i]) == false)
continue;
check[i] = true;
answer.push_back(wordList[i]);
if (dfs(wordList[i], endWord, wordList, count + 1))
movable = true;
answer.pop_back();
check[i] = false;
}
if (movable == false)
counts[curWord] = count;
return movable;
}
bool isNearWord(string& cur, string& next) {
int cnt = 0;
for (int i = 0; i < cur.size(); i++)
if (cur[i] != next[i])
cnt++;
return cnt == 1;
}
};
λ¬Έμ : left to right
https://leetcode.com/problems/candy/description/
LeetCode - The World's Leading Online Programming Learning Platform
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
#include <vector>
using namespace std;
class Solution {
public:
int candy(vector<int>& ratings) {
int n = ratings.size();
vector<int> candyCount(n, 1);
// left to right
for (int i = 1; i < n; ++i) {
if (ratings[i - 1] < ratings[i]) {
candyCount[i] = candyCount[i - 1] + 1;
}
}
// right to left
for (int i = n - 2; i >= 0; --i) {
if (ratings[i] > ratings[i + 1]) {
candyCount[i] = max(candyCount[i], candyCount[i + 1] + 1);
}
}
int answer = 0;
for (int i = 0; i < candyCount.size(); ++i)
answer += candyCount[i];
return answer;
}
};
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
LeetCode - The World's Leading Online Programming Learning Platform
Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.
leetcode.com
#include <vector>
#include <math.h>
using namespace std;
class Solution {
public:
int maxProfit(vector<int>& prices) {
int size = prices.size();
vector<int> leftProfit(size, 0);
vector<int> rightProfit(size, 0);
int minPrice = prices[0];
for (int i = 1; i < size; ++i) {
minPrice = min(prices[i], minPrice);
leftProfit[i] = max(leftProfit[i - 1], prices[i] - minPrice);
}
int maxPrice = prices[size - 1];
for (int i = size - 2; i >= 0; --i) {
maxPrice = max(prices[i], maxPrice);
rightProfit[i] = max(rightProfit[i + 1], maxPrice - prices[i]);
}
int answer = 0;
for (int i = 0; i < size; ++i)
answer = max(answer, leftProfit[i] + rightProfit[i]);
return answer;
}
};