[BOJ] 7579 앱

Table Of Contents

https://www.acmicpc.net/problem/7579

N개의 앱

A_1, ..., A_N
이 있다. 앱
A_i
m_i
의 메모리를 사용중이고, 이를 비활성한 후 다시 실행할 때
c_i
의 비용이 든다. 이 중에서 몇 개를 비활성화시켜 M 이상의 메모리를 확보하는 동시에,
c_i
의 합을 최소로 만드는 문제이다.

1 \leq N \leq 100 \newline 1 \leq M \leq 10,000,000 \newline 1 \leq m_1, ..., m_N \leq 10,000,000 \newline 0 \leq c_1, ..., c_N \leq 100 \newline M \leq m_1 + m_2 + ... + m_N

따라서 점화식은 다음처럼 세운다.

  1. 앱 i를 비활성화시키지 않는 경우
    • dp[i][j]는 1 ~ i-1번째 앱 중 몇 개를 비활성화시키고 재실행 비용이 j일 때의 확보 가능한 최대 메모리와 같다.
    • 따라서 dp[i][j] = dp[i - 1][j]이다.
  2. 앱 i를 비활성화시키는 경우
    • 앱 i의 재실행 비용을 c, 앱 i를 비활성화시켜 확보할 수 있는 메모리를 m이라고 한다.
    • i - 1번째까지를 고려했을 때 비용이 j - c인 상황에서 앱 i를 비활성화시켜야 한다.
    • 따라서 dp[i][j] = dp[i - 1][j - c]이다.
  3. 같은 비용으로 더 많은 메모리를 확보하는 것이 이득이므로 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - c])이다.
#include <iostream> #include <vector> using namespace std; int N, M, m[101], c; vector<vector<int> > dp; // dp[N][N*c] int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N >> M; for (int i = 1; i <= N; i++) cin >> m[i]; dp.resize(N + 1, vector<int>(10001, 0)); for (int i = 1; i <= N; i++) { cin >> c; for (int j = 0; j <= 10000; j++) { dp[i][j] = dp[i - 1][j]; if (j >= c) dp[i][j] = max(dp[i][j], dp[i - 1][j - c] + m[i]); } } for (int j = 0; j <= 10000; j++) { if (dp[N][j] >= M) { cout << j; return 0; } } return 0; }