일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 마이크로프로세서
- 소프티어
- 구현
- 루돌프의반란
- 마법의숲탐색
- 토끼와 경주
- 이진탐색
- ARM
- ICER
- BFS
- 수영대회결승전
- 삼성기출
- ISER
- 조합
- 코드트리빵
- 코드트리
- 순서대로방문하기
- ros
- 시뮬레이션
- 싸움땅
- dfs
- DP
- DenseDepth
- 3Dreconstruction
- 포탑부수기
- 백준
- 나무박멸
- 왕실의기사대결
- 슈퍼컴퓨터클러스터
- Calibration
Archives
- Today
- Total
from palette import colorful_colors
[SWEA] 3234 준환이의 양팔저울 with C++ 본문
가지치기를 2번 해줘야 한다
// 최악의 케이스 경우도 int를 넘지는 않음. (1억 8천 회). 단 1초는 넘음(1억회 이상이니깐)
// 처음엔 순열 다 만들고 각 경우마다 테스트할랬는데 20에서 시간초과
// -> 순열 만들면서 동시에 판단하기
// 가지치기 2개
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <cmath>
#include <stdio.h>
using namespace std;
int T, N, answer, totalWeight;
int choo[10];
int visited[10]; // 순열 만들기 위한 체크 함수
//int factorial[] = {0, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; 이거 써봤자 의미 거의 없음
void init() {
memset(choo, 0, sizeof(choo));
answer = 0;
totalWeight = 0;
}
void input() {
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> choo[i];
totalWeight += choo[i];
}
}
// 팩토리얼을 위한 함수 구현
int factorial(int num) {
if (num == 1)
return num;
int ret = num * factorial(num - 1);
return ret;
}
void func(int level, int leftWeight, int rightWeight, int remainedWeight) {
if (level == N) {
answer++;
return;
}
// 가지치기1: 이게 true면 남은것들 왼쪽 오른쪽 순열 걱정없이 아무렇게나 올릴 수 있음. 바로 return
bool returnNow = (leftWeight >= (rightWeight + remainedWeight));
if (returnNow) {
answer += pow(2, N - level) * factorial(N - level); // 주의 ! 2^남은 경우로 만들 수 있는 부분집합 X 남은 순열 가지수
return;
}
for (int i = 0; i < N; i++)
{
if (visited[i] == 1) continue;
visited[i] = 1;
// 가지치기2: 현재 추를 오른쪽에 올렸을때 더 무겁다면 남아 있는 것들은 무조건 왼쪽에 다 올려야함.
bool isLeft = (leftWeight < rightWeight + choo[i]);
if (isLeft) {
func(level + 1, leftWeight + choo[i], rightWeight, remainedWeight - choo[i]);
}
else {
func(level + 1, leftWeight + choo[i], rightWeight, remainedWeight - choo[i]);
func(level + 1, leftWeight, rightWeight + choo[i], remainedWeight - choo[i]);
}
visited[i] = 0;
}
}
void solve() {
func(0, 0, 0, totalWeight);
}
int main() {
freopen("sample_input.txt", "r", stdin);
cin >> T;
for (int tc = 1; tc <= T; tc++)
{
init();
input();
solve();
cout << "#" << tc << " " << answer << "\n";
}
return 0;
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
[백준] 15683 감시 with C++ (삼성기출) (0) | 2024.03.31 |
---|---|
[SWEA] 1949 등산로 조성 with C++ (0) | 2024.03.03 |
[백준] 16236 아기상어 with C++ (0) | 2024.02.22 |
[SWEA] 2382 미생물 격리 with C++ (0) | 2024.02.21 |
[백준] 14503 로봇 청소기 with C++ (삼성기출) (1) | 2024.02.19 |