Problem Solving/Else
Problem Solving @ 2022/04/21
PS리버싱마크해커박종휘TV
2022. 4. 21. 15:48
중간고사가 다가오네요. 그 와중에 PS를 하고 있습니다.
1. 숫자 박스 (G2) - KOI 2003 고등부 2번
시간 복잡도: O(N^3)
알고리즘: DP
Only DP 문제입니다. dp 테이블을 다음과 같이 나타냅시다.
≫ dp[idx][a][b] = idx까지 숫자를 설치했을 때, 1번째 줄의 박스를 a개, 2번째 줄의 박스를 b개 설치했을 때 최댓값
4가지 방법이 있습니다.
- 1번째 줄에 a번째 박스만 설치하기
- 2번째 줄에 b번째 박스만 설치하기
- 둘 다 설치 안하기
- 둘 다 설치하기
여기서 3번째 경우는 항상 손해이므로 배제해서, dp 테이블을 채워나갑니다. 예외 처리를 많이 해주어야 하는 것이 포인트입니다.
더보기
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 999999999
int N, A = 1, B = 1;
int dp[401][401][401];
int aarr[401], barr[401];
int solve(int idx, int a, int b) {
if (a == A + 1 || b == B + 1) return 0;
int& cache = dp[idx][a][b];
if (cache != -INF) return cache;
if (N + a > idx + A) cache = max(cache, solve(idx + 1, a, b + 1));
if (N + b > idx + B) cache = max(cache, solve(idx + 1, a + 1, b));
cache = max(cache, solve(idx + 1, a + 1, b + 1) + aarr[a] * barr[b]);
return cache;
}
int main() {
cin >> N;
for (int i = 0; i < N; i++) {
int inp; cin >> inp;
if (inp != 0) { aarr[A] = inp; A++; }
}
for (int i = 0; i < N; i++) {
int inp; cin >> inp;
if (inp != 0) { barr[B] = inp; B++; }
}
A--; B--;
for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) for (int k = 1; k <= N; k++) dp[i][j][k] = -INF;
cout << solve(1, 1, 1) << endl;
}
2. 누적 거리 (G2) - KOI 2021 2차대회 중등부 2번
설명은 사진 딱 한 장으로 충분합니다. 사진에서 psum은 누적 합이라는 뜻입니다.
더보기
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
int N, Q;
int pa[200001][2], pax[200001][2];
pair<int, int> ax[200001]; int x[200001];
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> N >> Q;
for (int i = 0; i < N; i++) {
int a, xi; cin >> a >> xi;
ax[i] = { xi, a }; x[i] = xi;
}
sort(ax, ax + N); sort(x, x + N);
pax[0][0] = (int)(ax[0].first * ax[0].second); pa[0][0] = (int)(ax[0].second);
for (int i = 1; i < N; i++) {
pax[i][0] = (int)(ax[i].first * ax[i].second); pax[i][0] += pax[i - 1][0];
pa[i][0] = (int)(ax[i].second); pa[i][0] += pa[i - 1][0];
}
pax[N - 1][1] = (int)(ax[N - 1].first * ax[N - 1].second); pa[N - 1][1] = (int)(ax[N - 1].second);
for (int i = N - 2; i >= 0; i--) {
pax[i][1] = (int)(ax[i].first * ax[i].second); pax[i][1] += pax[i + 1][1];
pa[i][1] = (int)(ax[i].second); pa[i][1] += pa[i + 1][1];
}
for (int i = 0; i < Q; i++) {
int query; cin >> query;
int idx = lower_bound(x, x + N, query) - x;
int first_sigma = (int)(pa[idx - 1][0] * query) - pax[idx - 1][0];
int second_sigma = pax[idx][1] - (int)(pa[idx][1] * query);
//cout << "idx: " << idx << ", pax: " << pax[idx - 1][0] << ", fsig: " << first_sigma << ", ssig: " << second_sigma << endl;
cout << first_sigma + second_sigma << '\n';
}
}