-
2024-03-11PS(알고리즘 문제풀이) 관련 글/PS일지 2024. 3. 11. 23:14
-방배정(13304, 백준)
간단 한 문제이다. {1~2학년 남녀}, {3~4학년 남}, {3~4학년 여}, {5~6학년 남}, {5~6학년 여}그룹으로 나누어 풀면 된다. 입력 받은수가 어느 그룹에 속하는지를 확인하고 구하면 풀린다.
<소스 코드>
더보기#include <stdio.h> int low, mid_ma, mid_fe, high_ma, high_fe; int n, k; int main() { int i, j; scanf("%d %d", &n, &k); for (i = 0; i < n; i++) { int x, y; scanf("%d %d", &y, &x); if (1 <= x && x <= 2) low++; else if (3 <= x && x <= 4) { if (y == 1) mid_ma++; else mid_fe++; } else if (5 <= x && x <= 6) { if (y == 1) high_ma++; else high_fe++; } } int ans = (low / k) + (mid_ma / k) + (mid_fe / k) + (high_ma / k) + (high_fe / k); if (low % k > 0) ans++; if (mid_ma % k > 0) ans++; if (mid_fe % k > 0) ans++; if (high_ma % k > 0) ans++; if (high_fe % k > 0) ans++; printf("%d", ans); return 0; }
-주유소(13305, 백준)
그리디 문제이다. 앞에서부터 최솟값을 갱신해주며 최솟값에 거리를 곱해주었다.
<소스 코드>
더보기#include <stdio.h> #include <algorithm> using namespace std; long long n; long long val[100010], way[100010]; long long ans; int main() { long long i, j; scanf("%lld", &n); for (i = 1; i < n; i++) scanf("%lld", &way[i]); for (i = 1; i <= n; i++) scanf("%lld", &val[i]); long long mn = 2e9; for (i = 1; i < n; i++) { mn = min(mn, val[i]); ans += mn * way[i]; } printf("%lld", ans); return 0; }
-리조트(13302, 백준)
2차원 DP문제이다. 간단하게 생각하고 풀었다가 한참 고민했던 문제였다. Dp[i][j] = j개의 쿠폰을 갖고 i일까지의 최솟값으로 두고 푼다. 경우를 나누어 풀면 쉽게 풀 수 있다.
1) 리조트에 가지않는 날
2) 1일권을 사는 경우
3) 3일권을 사는 경우
4) 5일권을 사는 경우
3일권과 5일권을 사용중일때, 또 이용권을 사는 반례가 있음에 주의하자.
>점화식<
더보기1) dp[i + 1][j] = min(dp[i][j], dp[i + 1][j]);
2) dp[i + 1][j] = min(dp[i][j] + 10, dp[i + 1][j]);3) for (int l = 1; l <= 3; l++) dp[i + l][j + 1] = min(dp[i][j] + 25, dp[i + l][j + 1]);
4) for (int l = 1; l <= 5; l++) dp[i + l][j + 2] = min(dp[i][j] + 37, dp[i + l][j + 2]);
<소스 코드>
더보기#include <stdio.h> #include <algorithm> using namespace std; int n, m; int ch[110]; int dp[210][210]; int main() { int i, j; scanf("%d %d", &n, &m); for (i = 1; i <= m; i++) { int x; scanf("%d", &x); ch[x] = 1; } if (n == m) { printf("0"); return 0; } for (i = 0; i <= n + 5; i++) { for (j = 0; j <= n + 5; j++) { dp[i][j] = 2e9; } } dp[0][0] = 0; for (i = 0; i <= n; i++) { for (j = 0; j <= n; j++) { if (dp[i][j] == 2e9) continue; if (ch[i + 1] == 1) dp[i + 1][j] = min(dp[i][j], dp[i + 1][j]); dp[i + 1][j] = min(dp[i][j] + 10, dp[i + 1][j]); if (j >= 3) dp[i + 1][j - 3] = min(dp[i + 1][j - 3], dp[i][j]); for (int l = 1; l <= 3; l++) dp[i + l][j + 1] = min(dp[i][j] + 25, dp[i + l][j + 1]); for (int l = 1; l <= 5; l++) dp[i + l][j + 2] = min(dp[i][j] + 37, dp[i + l][j + 2]); } } int ans = 2e9; for (i = 0; i <= n; i++) ans = min(ans, dp[n][i]); long long res = ans * 1000; printf("%lld", res); return 0; }
-상자넣기(1965, 백준)
문제를 읽으면 누가봐도 LIS이다. LIS를 알면 아주 쉽게 풀린다. O(n^2)으로도 풀림
<소스 코드>
더보기#include <stdio.h> #include <algorithm> #include <vector> using namespace std; int n; int arr[1010]; vector <int> lis; int main() { int i, j; scanf("%d", &n); for (i = 0; i < n; i++) scanf("%d", &arr[i]); lis.push_back(arr[0]); for (i = 1; i < n; i++) { int lb = lower_bound(lis.begin(), lis.end(), arr[i]) - lis.begin(); int sz = lis.size(); if (lb >= sz) lis.push_back(arr[i]); else lis[lb] = arr[i]; } printf("%d", lis.size()); return 0; }
-동물원(1309, 백준)
규칙 찾다가 뒤에 비어있는게 예외처리가 되길래 배열 2개로 풀어서 합쳤다. Dp[i][0] = 끝의 칸이 비어있는 경우 Dp[i][1] = 끝의 칸이 채워져있는 경우로 두고 구현해 풀었다. 1차원으로도 쉽게 풀린덴다.(뇌가 멍청해진 것같다.)
>점화식<
더보기dp[i][0] = (dp[i - 1][0] + dp[i - 1][1])
dp[i][1] = (dp[i - 1][0] * 2 + dp[i - 1][1])
<소스 코드>
더보기#include <stdio.h> #include <algorithm> using namespace std; int dp[100010][2]; int n; int main() { int i, j; scanf("%d", &n); dp[1][0] = 1; dp[1][1] = 2; for (i = 2; i <= n; i++) { dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % 9901; dp[i][1] = (dp[i - 1][0] * 2 + dp[i - 1][1]) % 9901; } printf("%d", (dp[n][0] + dp[n][1]) % 9901); return 0; }
'PS(알고리즘 문제풀이) 관련 글 > PS일지' 카테고리의 다른 글
2024-03-13 (0) 2024.03.13 2024-03-12 (1) 2024.03.12 2024-03-10 (0) 2024.03.10 2024-03-09 (0) 2024.03.09 2024-03-08 (0) 2024.03.08