백준 10321 - 요새 건설
2025/01/13
NEW POST
Jinsoolve.
Categories
Tags
1월 안에는 꼭...
About
dp[i][0]
:= 1~i 까지 문제를 푸는데, i를 풀고 나서 남은 코인의 갯수가 0개일 때의 최댓값
dp[i][1]
:= 1~i 가지 문제를 푸는데, i를 풀고 나서 남은 코인의 갯수와 상관없이 최댓값
위 처럼 2가지 dp를 저장한다고 하자.
먼저 dp[i][0]
를 생각해보자.
dp[i-m][0] + (scoreAcc[i] - scoreAcc[i-m]) + bonus[i]
dp[i-m][0]
(scoreAcc[i] - scoreAcc[i-m]) + bonus[i]
dp[i-1][1] - score[i]
그럼 이번에는 dp[i][1]
을 생각해보자.
dp[i][0]
에서 이미 1-1번과 2번을 모두 계산했음을 알 수 있다.dp[i-1][1] + score[i]
이다.여기서 의문의 생기는데 dp[i-1][1] + score[i]
에서 i-1까지의 최댓값 상황에서 코인이 몇 개인지 알아야 i번째에 보너스를 더할지 안 더할지를 할 수 있지 않을까라는 의문이 생길 수 있다.
그러나, 만약 i번째에서 M개를 채웠다면 이는 결국 1-1이다. 그리고 점수들은 모두 음이 아닌 정수이므로 무조건 1-1의 경우가 저장된 dp[i][0]
가 클 것이고 결국 max
함수로 비교하면 이를 덮어씌울 것이다. 따라서 우리는 dp[i-1][1]
이 몇 개의 코인을 모았는지 신경쓸 필요가 없다.
1#include <bits/stdc++.h> 2 3#define endl "\n" 4#define all(v) (v).begin(), (v).end() 5#define For(i, a, b) for(int i=(a); i<(b); i++) 6#define FOR(i, a, b) for(int i=(a); i<=(b); i++) 7#define Bor(i, a, b) for(int i=(a)-1; i>=(b); i--) 8#define BOR(i, a, b) for(int i=(a); i>=(b); i--) 9#define ft first 10#define sd second 11 12using namespace std; 13using ll = long long; 14using lll = __int128_t; 15using ulll = __uint128_t; 16using ull = unsigned long long; 17using ld = long double; 18using pii = pair<int, int>; 19using pll = pair<ll, ll>; 20using ti3 = tuple<int, int, int>; 21using tl3 = tuple<ll, ll, ll>; 22 23template<typename T> using ve = vector<T>; 24template<typename T> using vve = vector<vector<T>>; 25 26template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; } 27template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } 28 29const int INF = 987654321; 30const int INF0 = numeric_limits<int>::max(); 31const ll LNF = 987654321987654321; 32const ll LNF0 = numeric_limits<ll>::max(); 33 34int n, m; 35ve<ll> score, bonus, scoreAcc; 36vve<ll> dp; 37 38void solve() { 39 cin >> n >> m; 40 score = ve<ll>(n+1,0); 41 bonus = ve<ll>(n+1,0); 42 scoreAcc = ve<ll>(n+1,0); 43 dp = vve<ll>(n+1, ve<ll>(2, -INF0)); 44 45 FOR(i,1,n) { 46 cin >> score[i]; 47 scoreAcc[i] = score[i] + scoreAcc[i-1]; 48 } 49 FOR(i,1,n) cin >> bonus[i]; 50 51 dp[0][0] = dp[0][1] = 0; 52 FOR(i,1,n) { 53 ckmax(dp[i][0], dp[i-1][1] - score[i]); 54 if(i-m>=0) ckmax(dp[i][0], scoreAcc[i]-scoreAcc[i-m] + bonus[i] + dp[i-m][0]); 55 56 ckmax(dp[i][1], dp[i][0]); 57 ckmax(dp[i][1], dp[i-1][1] + score[i]); 58 } 59 cout << dp[n][1] << endl; 60} 61 62int main(void) { 63 ios_base::sync_with_stdio(false); 64 cin.tie(nullptr); 65 cout.tie(nullptr); 66 67 int TC=1; 68// cin >> TC; 69 FOR(tc, 1, TC) { 70// cout << "Case #" << tc << ": "; 71 solve(); 72 } 73 74 75 return 0; 76}