본문 바로가기

Problem Solving/문제풀이

백준 11001번 김치

반응형

문제 요약

김치를 i일에 넣고 j일에 꺼낸다면 이 김치의 맛은 (ji)Tj+Vi로 정의된다. Tjj번째 날의 온도이며, Vii번째 날의 김치의 가치다.

이 때, 최대 D만큼만 김치를 숙성시킬 수 있다. (jiD), Ti,Vi가 N개만큼 주어질 때 만들 수 있는 최대 김치의 맛을 구해라

N은 최대 10만이다.

풀이

C(i,j)i번째 날에 김치를 넣어서 j번째 날에 꺼낸 김치의 맛으로 정하자.
C(i,j)=(ji)Tj+Vi
문제의 조건에서 TiTi+1이라고 했다.

넣은 날을 i번째 날로 고정했을 때 꺼냈을 때 제일 맛있는 날을 opti라고 하자.

그러면 위 조건 때문에 i<i일 때, opti,opti임을 증명할 수 있다.

따라서, 분할정복 최적화를 적용할 수 있다. 최대 D일 만큼만 넣을 수 있다는 조건만 주의하자.

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

vector<ll> T, V, dp;
int D, N;
ll ans;
ll cnt;
ll C(ll i, ll j) {
    return V[i] + (j-i) * T[j];
}

void solve(int s, int e, int optl, int optr) {
    if(s > e) return ;
    int mid = (s+e) >> 1;
    int opt = mid;
    dp[mid] = V[mid];
    pair<ll,int> ret = {V[mid],mid};
    for(int i=optl;i<=min(optr, mid+D);++i) {
        ll val = V[mid] + (i - mid) * T[i];
        if(dp[mid] < val) {
            dp[mid] = val; opt = i;
        }
    }
    solve(s, mid-1, optl, opt);
    solve(mid+1, e, opt, optr);
}

int main() {
    cin.tie(nullptr); ios::sync_with_stdio(false);
    cin >> N >> D;
    T.resize(N+1); V.resize(N+1); dp.resize(N+1);
    for(int i=1;i<=N;++i) cin >> T[i];
    for(int i=1;i<=N;++i) cin >> V[i];
    solve(1,N,1,N);
    for(int i=1;i<=N;++i) ans = max(ans, dp[i]);
    cout << ans << '\n';
    return 0;
}
반응형

'Problem Solving > 문제풀이' 카테고리의 다른 글