https://www.acmicpc.net/problem/2229
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//dp[i]: i번째 학생까지의 조가 잘 짜여진 정도의 최댓값
int dp[1000];
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin>>n;
vector<int> arr(n);
for(int i=0;i<n;i++){
cin>>arr[i];
}
for(int i=0;i<n;i++){
int mnum=arr[i];
int Mnum=arr[i];
for(int j=i;j>=0;j--){
Mnum=max(Mnum, arr[j]);
mnum=min(mnum, arr[j]);
dp[i+1]=max(dp[i+1], dp[j]+Mnum-mnum);
}
}
cout<<dp[n];
}
1. 문제
알고스팟 캠프에 N(1 ≤ N ≤ 1,000)명의 학생들이 참여하였다. 학생들은 열심히 공부를 하고 있었는데, 어느 날 조별 수업을 진행하기로 하였다. 조별 수업의 목적은 잘 하는 학생들과 덜 잘 하는 학생들을 같은 조로 묶어서 서로 자극을 받으며 공부하도록 만들기 위함이다. 따라서 가급적이면 실력 차이가 많이 나도록 조를 편성하는 것이 유리하다.
하지만 조를 편성할 때 같은 조에 속하게 된 학생들의 나이 차이가 많이 날 경우에는 오히려 부정적인 효과가 나타날 수도 있다. 따라서 선생님들은 우선 학생들을 나이 순서대로 정렬한 다음에, 적당히 학생들을 나누는 방식으로 조를 짜기로 하였다. 조의 개수는 상관이 없다.
각각의 조가 잘 짜여진 정도는 그 조에 속해있는 가장 점수가 높은 학생의 점수와 가장 점수가 낮은 학생의 점수의 차이가 된다. 또한 전체적으로 조가 잘 짜여진 정도는, 각각의 조가 잘 짜여진 정도의 합으로 나타난다. 한 명으로 조가 구성되는 경우에는 그 조의 잘 짜여진 정도가 0이 된다(가장 높은 점수와 가장 낮은 점수가 같으므로).
학생들의 점수가 주어졌을 때, 조가 잘 짜여진 정도의 최댓값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N이 주어진다. 다음 줄에는 N명의 학생들의 점수가 나이 순서대로 주어진다. 각 학생의 점수는 0 이상 10,000 이하의 정수이다.
출력
첫째 줄에 답을 출력한다.
2. 풀이
dp[i]: i번째 학생까지 모아 조를 짰을 때 잘 짜여진 정도의 최댓값이라 하자.
for(int i=0;i<n;i++){
int mnum=arr[i];
int Mnum=arr[i];
for(int j=i;j>=0;j--){
Mnum=max(Mnum, arr[j]);
mnum=min(mnum, arr[j]);
dp[i+1]=max(dp[i+1], dp[j]+Mnum-mnum);
}
}
i+1번 학생까지를 1번째부터 j번째까지, j+1번째부터 i번째까지의 2개 조로 나누어보자.
- Mnum: j+1번째부터 i번째까지 학생 중 최대 점수
- mnum: j+1번째부터 i번째까지 학생 중 최소 점수
이렇게 계산하면 점화식은 다음과 같이 나온다
- (i명으로 잘 짜여진 정도의 최댓값)=max(현재 값, j번째까지의 합+(j+1번째부터 i번째까지의 합))
연산 후 dp[n]을 출력하면 정답을 구할 수 있다.
'Coding Test' 카테고리의 다른 글
| Leetcode 921 Minimum Add to Make Parentheses Valid (Java) (1) | 2024.10.09 |
|---|---|
| 백준 6497 전력난 (Java) (0) | 2024.10.06 |
| 백준 16973 직사각형 탈출 (Java) (2) | 2024.10.03 |
| 백준 1963 소수 경로 (Java) (1) | 2024.10.02 |
| 백준 12886 돌 그룹 (C++) (1) | 2024.09.27 |