1. 문제
1) 문제 링크
: www.acmicpc.net/problem/7579
7579번: 앱
입력은 3줄로 이루어져 있다. 첫 줄에는 정수 N과 M이 공백문자로 구분되어 주어지며, 둘째 줄과 셋째 줄에는 각각 N개의 정수가 공백문자로 구분되어 주어진다. 둘째 줄의 N개의 정수는 현재 활
www.acmicpc.net
2) 설명
각각의 프로세스가 메모리를 m_i만큼 사용하고 있고, 각 프로세스를 비활성화시킬 때 드는 비용이 c_i라면, 최소 M만큼의 메모리 공간을 확보하는 데 필요한 최소 비용을 구하는 문제
2. 풀이
1) 알고리즘
: DP(배낭)
2) 풀이 설명
A) 첫 시도 : 2차원 배열 사용하기
- 처음에는 메모리 생각을 안 하고 100(N 최댓값) x 10000000(M 최댓값) 2차원 배열을 사용했다.
메모리 초과가 나서 안 되니까 map을 사용해보자는 생각으로 map을 사용했지만 역시나 메모리 초과로 실패했다. (어차피 사용량 많아지면 비슷해지는 것 같다)
B) 두번째 시도 : 1차원 배열 사용하기
- 한참 고민하다가 결국 다른 사람들 풀이를 참고해서 풀게 되었다.
dp 배열 : 1차원 배열로 dp[cost] : cost를 사용해서 최대로 확보할 수 있는 memory
이제 이중 반복문을 통해 dp 배열을 업데이트해나갔다.
점화식 : dp[j] = max(dp[j], dp[j - C[i]] + A[i])
i번째 프로세스를 비활성화할 경우 dp 배열을 업데이트 해나가는 점화식이다.
만약 활성화된 채로 두는 게 더 큰 memory를 확보할 수 있다면 dp[j] 가 선택 될 것이고, 비활성화하는 게 더 큰 메모리를 확보할 수 있다면 dp[j-C[i]] + A[i] 가 선택될 것이다.
3. 코드
/*
앱
DP
1차원 배열을 사용한 풀이
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#define N_MAX 100
#define C_MAX 100
#define M_MAX 10000000
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int N, M, maxCost, answer;
vector<int> A(N_MAX, 0), C(N_MAX, 0);
vector<int> dp(N_MAX*C_MAX + 1, 0);
cin >> N >> M;
for(int i=0;i<N;i++) cin >> A[i];
for(int i=0;i<N;i++) cin >> C[i];
maxCost = accumulate(C.begin(), C.end(), 0);
for(int i=0;i<N;i++)
for(int j=maxCost;j>=C[i];j--)
dp[j] = max(dp[j], dp[j - C[i]] + A[i]);
for(answer=0;answer<maxCost && dp[answer]<M;answer++);
cout << answer << "\n";
}
/*
앱
DP
vector와 map을 중첩하여 사용한 풀이
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#define N_MAX 100
#define C_MAX 100
#define M_MAX 10000000
using namespace std;
int N, M;
vector<int> A(N_MAX, 0), C(N_MAX, 0);
vector<map<int, int>> dp(N_MAX);
int solve(int idx, int needMemory){
if(idx >= N)
return M_MAX;
if(needMemory <= 0)
return 0;
if(dp[idx][needMemory] <= 0)
dp[idx][needMemory] = min(solve(idx + 1, needMemory), C[idx] + solve(idx + 1, needMemory - A[idx]));
return dp[idx][needMemory];
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N >> M;
for(int i=0;i<N;i++) cin >> A[i];
for(int i=0;i<N;i++) cin >> C[i];
cout << solve(0, M) << endl;
}
4. 느낀점
1) 좀 더 다방면의 방법을 생각해야겠다. 너무 N, M 값에만 집중해서 생각하다보니 다른 방법을 잘 못 찾았다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준/2110] 공유기 설치 (0) | 2021.08.01 |
---|---|
[BOJ/1034] 램 (0) | 2021.07.27 |
[BOJ/14891] 톱니바퀴 (0) | 2020.12.18 |
[백준/9656] 돌 게임 2 (0) | 2020.11.02 |
[백준/2631] 줄세우기 (0) | 2020.11.02 |