https://www.acmicpc.net/problem/20303
20303번: 할로윈의 양아치
첫째 줄에 정수 $N$, $M$, $K$가 주어진다. $N$은 거리에 있는 아이들의 수, $M$은 아이들의 친구 관계 수, $K$는 울음소리가 공명하기 위한 최소 아이의 수이다. ($1 \leq N \leq 30\ 000$, $0 \leq M \leq 100\ 000$,
www.acmicpc.net
솔루션
친구들을 하나의 묶음으로 묶고 냅색을 수행하면 된다.
1. bfs를 이용해 그룹의 인원과, 사탕의 총 개수를 구한다.
2. 냅색을 이용한다..
(오랜만에 글을 써서.. 그런가.. 엄청 짧다..)
코드
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int N, M, K;
int V[30002];
vector<int> edge[30002];
bool visit[30002];
int num = 0;
int dp[30002][3002];
vector<pair<int, int>> group;
void makeSet(int cur) {
queue<int> Q;
Q.push(cur);
visit[cur] = true;
int w = 0;
int num = 0;
while (!Q.empty()) {
int cur = Q.front();
Q.pop();
num++;
w += V[cur];
for (auto& next : edge[cur]) {
if (!visit[next]) {
Q.push(next);
visit[next] = true;
}
}
}
group.push_back({ num,w });
return;
}
int solve(void) {
for (int i = group[0].first; i < K; i++) {
dp[0][i] = group[0].second;
}
for (int i = 1; i < group.size(); i++) {
for (int j = 0; j < K; j++) {
if (j - group[i].first >=0) {
dp[i][j] = dp[i - 1][j - group[i].first] + group[i].second;
}
dp[i][j] = max(dp[i - 1][j], dp[i][j]);
}
}
return dp[group.size() - 1][K - 1];
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N >> M >> K;
for (int i = 1; i <= N; i++) {
cin >> V[i];
}
for (int i = 0; i < M; i++) {
int str, end;
cin >> str >> end;
edge[str].push_back(end);
edge[end].push_back(str);
}
for (int i = 1; i <= N; i++) {
if (!visit[i]) {
num = 0;
makeSet(i);
}
}
cout << solve() << '\n';
}
'백준' 카테고리의 다른 글
C++[백준]1493번 박스 채우기 (1) | 2023.10.25 |
---|---|
C++[백준]20529 가장 가까운 세 사람의 심리적 거리 (0) | 2023.07.11 |
C++[백준]1915번 가장 큰 정사각형 (0) | 2023.06.23 |
C++[백준]22342번 계산 로봇 (0) | 2023.06.23 |
C++[백준]14846번 직사각형과 쿼리 (0) | 2023.05.29 |