양의 정수인 w와 양의 정수인 W가 주어진다.
⇒ 각 노드의 가중치인 w와 우리가 구해야하는 노드들의 합인 W가 주어진다.
이 알고리즘의 목표는 노드의 가중치의 합이 W가 되는 모든 subset을 찾는 것이다.
가중치를 오름차순으로 정렬
: 레벨의 가중치까지의 합
⇒ non-promising
현재까지의 합 + 다음 노드 > 구해야 하는 값
: 남아있는 노드들의 합(현재 노드에서 최대로 더할 수 있는 가중치의 합)
⇒ non-promising
현재까지의 합 + 앞으로 얻을 수 있는 값 < 구해야 하는 값
즉, 현재까지의 합에서 남아있는걸 더 더해봤자, 내가 원하는 값이 나오지 않으면 유망하지 않다.
void sum_of_subsets( int i, int weight, int total)
{
if(promising(i)){
if(weight == W) cout<< include[1]~include[i];
else{
include[i+1] = "yes";
sum_of_subsets(i+1, weight + w[i+1], total - w[i+1]);
include[i+1] = "no";
sum_of_subsets(i+1, weight, total - w[i+1]);
}
}
bool promising(index i)
{
return (weight + total > = w)
&& (weight == W || weight + w[i+1] <= W);
}
1️⃣ weight + total ≥ W
먼저 답이 될 수 있는지를 체크한다. 만약에 더해질 수 있는 값이
구해야하는 값보다 크거나 같아야 답일 수 있기 때문이다.
2️⃣ (weight == W) || 3️⃣ (weight + w[i + 1] ≤ W)
만약, 2️⃣답이거나 3️⃣ 자식과 더했을 때 답보다 더 작은 값이거나 같으면
유망하므로 1을 리턴한다.
최악의 상황 가정하기
: n개의 노드가 있을 때, 첫번째 노드에서 n-1번째 노드까지는 모두 더해서 W를 만족시키지 못하지만, 마지막 노드인 n번째 노드 == W일 때
지수 이상 걸리고, 다른 알고리즘 사용해도 지수보다 좋지 못하며, 그러한 알고리즘이 존재하지 않는다는 것을 증명한 사람도 없다.