알고리즘

[백준] BOJ 7579번 앱

staktree 2023. 11. 29. 18:12


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

 

7579번: 앱

입력은 3줄로 이루어져 있다. 첫 줄에는 정수 N과 M이 공백문자로 구분되어 주어지며, 둘째 줄과 셋째 줄에는 각각 N개의 정수가 공백문자로 구분되어 주어진다. 둘째 줄의 N개의 정수는 현재 활

www.acmicpc.net

 

문제 :

우리는 스마트폰을 사용하면서 여러 가지 앱(App)을 실행하게 된다. 대개의 경우 화면에 보이는 ‘실행 중’인 앱은 하나뿐이지만 보이지 않는 상태로 많은 앱이 '활성화'되어 있다. 앱들이 활성화 되어 있다는 것은 화면에 보이지 않더라도 메인 메모리에 직전의 상태가 기록되어 있는 것을 말한다. 현재 실행 중이 아니더라도 이렇게 메모리에 남겨두는 이유는 사용자가 이전에 실행하던 앱을 다시 불러올 때에 직전의 상태를 메인 메모리로부터 읽어 들여 실행 준비를 빠르게 마치기 위해서이다.

하지만 스마트폰의 메모리는 제한적이기 때문에 한번이라도 실행했던 모든 앱을 활성화된 채로 메인 메모리에 남겨두다 보면 메모리 부족 상태가 오기 쉽다. 새로운 앱을 실행시키기 위해 필요한 메모리가 부족해지면 스마트폰의 운영체제는 활성화 되어 있는 앱들 중 몇 개를 선택하여 메모리로부터 삭제하는 수밖에 없다. 이러한 과정을 앱의 ‘비활성화’라고 한다.

메모리 부족 상황에서 활성화 되어 있는 앱들을 무작위로 필요한 메모리만큼 비활성화 하는 것은 좋은 방법이 아니다. 비활성화된 앱들을 재실행할 경우 그만큼 시간이 더 필요하기 때문이다. 여러분은 이러한 앱의 비활성화 문제를 스마트하게 해결하기 위한 프로그램을 작성해야 한다

현재 N개의 앱, A1, ..., AN이 활성화 되어 있다고 가정하자. 이들 앱 Ai는 각각 mi 바이트만큼의 메모리를 사용하고 있다. 또한, 앱 Ai를 비활성화한 후에 다시 실행하고자 할 경우, 추가적으로 들어가는 비용(시간 등)을 수치화 한 것을 ci 라고 하자. 이러한 상황에서 사용자가 새로운 앱 B를 실행하고자 하여, 추가로 M 바이트의 메모리가 필요하다고 하자. 즉, 현재 활성화 되어 있는 앱 A1, ..., AN 중에서 몇 개를 비활성화 하여 M 바이트 이상의 메모리를 추가로 확보해야 하는 것이다. 여러분은 그 중에서 비활성화 했을 경우의 비용 ci의 합을 최소화하여 필요한 메모리 M 바이트를 확보하는 방법을 찾아야 한다.

 

 

접근 : 
냅색문제의 변형 문제이다.
어플을 실행할 때마다 메모리가 필요한데, 메모리는 제한되어 있어 동시에 실행할 수 있는 어플의 개수는 유한하다. 새로운 어플이 실행되어야 할때 메모리가 부족한 경우가 있는데, 이때 기존에 실행 중이던 어플을 비활성화시켜 메모리를 확보하여 실행한다. 하지만 비활성화시키는데도 비용이든다. 최소비용으로 새로운 어플을 실행하기 위한 메모리를 확보해야한다.

해결 : 
작은 비용으로 더 많은 메모리를 확보해야한다. 따라서 비용을 기준으로 최대의 메모리를 가질 수 있는 경우를 메모제이션하여 해결한다. 현재 실행 중인 어플의 메모리와 비용을 입력받고, 해당 비용의 메모리를 메모제이션된 값과 비교시켜 더 큰 값을 다시 메모제이션한다. 메모제이션된 값들에 다음 차례의 어플의 비용을 더하다보면 모든 조합가능한 비용들을 계산할 수 있기 때문에 비용이 계산될 때마다 비교하여 큰 값을 저장한다. 마지막으로 메모제이션된 값 중 필요한 메모리인 M이상인 최소비용을 출력하면 된다.

 

#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
	int N, M;
	int memory[101] = {0, };
	int cost[101] = {0, };
	int DP[10001] = {0, };
	vector <int> calculatedCost;

	scanf("%d %d", &N, &M);
	for(int i = 0; i < N; i++)
	{
		scanf("%d", &memory[i]);
	}
	for(int i = 0; i < N; i++)
	{
		scanf("%d", &cost[i]);
	}

	for(int i = 0; i < N; i++)
	{
		int preCal = calculatedCost.size();
		for(int j = preCal - 1; j >=0; j--)
		{
			if(DP[cost[i] + calculatedCost[j]] == 0)
				calculatedCost.push_back(cost[i] + calculatedCost[j]);
				DP[cost[i] + calculatedCost[j]] = max(DP[cost[i] + calculatedCost[j]], DP[calculatedCost[j]] + memory[i]);
		}

		if(DP[cost[i]] == 0)
		calculatedCost.push_back(cost[i]);
		DP[cost[i]] = max(DP[cost[i]], memory[i]);
		sort(calculatedCost.begin(), calculatedCost.end());
	}

	for(int i = 0; i < calculatedCost.size(); i++)
	{
		int index = calculatedCost[i];
		if(DP[index] >= M)
		{
			printf("%d\n", index);
			break;
		}
	}
}

 

 

'알고리즘' 카테고리의 다른 글

[백준] BOJ 1920번 수 찾기  (2) 2023.12.04
[프로그래머스]소수 찾기(C++)  (2) 2023.12.02
[백준] BOJ 10830번 행렬 제곱  (2) 2023.11.27
[백준] BOJ 14501번 퇴사  (0) 2022.04.05
[백준] BOJ 13305번 주유소  (0) 2022.03.15