Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

D: スキャナー / Scanner

問題文

ここに $N$ 枚の紙がある。あなたは $3$ 台のスキャナーを並列に用いることで、
全ての紙をスキャンしたいと考えている。それぞれの紙はスキャンにかかる時間が決まっており、
$i$ 番目の紙をスキャンするのにかかる時間は $T_i$ である。
紙をスキャンする順番は任意であるが、$1$ 台のスキャナーで複数の紙を同時にスキャンすることはできない。

全ての紙のスキャンが終了し、スキャンを行っているスキャナーがなくなるまでにかかる時間を最小化しなさい。

入力

$N$

$T_1$

$T_2$

$T_3$

$\vdots$

$T_N$

制約

$1 \leq N \leq 50$

$1 \leq T_i \leq 50$

入力は全て整数

出力

答えを $1$ 行で出力してください．

サンプル

サンプル入力1

4
1
1
1
1

サンプル出力1

2

サンプル入力2

9
15
20
27
4
10
7
34
30
36

サンプル出力2

61

サンプル入力3

6
20
18
46
16
9
48

サンプル出力3

55

Solution in C++14 (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
#define FOR(i,s,t) for(int i = s; i< t ;i++)

#define SZ(x) (int)x.size()
using LL = long long; using ll = LL;
const int INF = 1e9; const LL LINF = 1e18;

#define MAXT 1005
ll N;
vector<int> T;
bool memo[55][MAXT][MAXT];

void dfs(int n, int x, int y,ll sum) {
	if (memo[n][x][y]) return;
	memo[n][x][y] = true;
	if (n == N) return;
	if (x + T[n] < MAXT) dfs(n + 1, x + T[n], y,sum + T[n]);
	if (y + T[n] < MAXT) dfs(n + 1, x, y + T[n],sum + T[n]);
	if (sum - x - y + T[n] < MAXT) dfs(n + 1, x, y, sum + T[n]);
}

void solve() {
	cin >> N;
	T.resize(N);
	for (auto& in : T) { cin >> in; }
	sort(T.begin(), T.end());
	reverse(T.begin(), T.end());
	dfs(0, 0, 0, 0);
	int sum = accumulate(T.begin(), T.end(), 0);

	ll ans = LINF;
	for (int i = 0; i < MAXT; i++) {
		for (int j = 0; j < MAXT; j++) {
			if (memo[N][i][j] == false) continue;
			ll t = -1;
			t = max({ i,j,sum - i - j });
			ans = min(ans, t);
		}
	}
	cout << ans << endl;
}


int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	solve();
	return 0;
}