using
System;
public
class
Settlement {
public
static
int
IntegerBitCount(
int
i)
{
i = i - ((i >> 1) & 1431655765);
i = (i & 858993459) + ((i >> 2) & 858993459);
i = (i + (i >> 4)) & 252645135;
i = i + (i >> 8);
i = i + (i >> 16);
return
i & 63;
}
}
public
class
GFG {
public
static
int
[, ] dp =
new
int
[1 << 20, 2];
public
static
int
findMinTime(
int
leftmask,
bool
turn,
int
[] arr,
int
n)
{
if
(leftmask == 0) {
return
0;
}
var
res = GFG.dp[leftmask, turn ==
true
? 1 : 0];
if
(~res != 0) {
return
res;
}
var
rightmask = ((1 << n) - 1) ^ leftmask;
if
(turn ==
true
) {
var
minRow =
int
.MaxValue;
var
person = 0;
for
(
int
i = 0; i < n; ++i) {
if
((rightmask & (1 << i)) != 0) {
if
(minRow > arr[i]) {
person = i;
minRow = arr[i];
}
}
}
res = arr[person]
+ GFG.findMinTime(leftmask
| (1 << person),
!turn, arr, n);
}
else
{
if
(Settlement.IntegerBitCount(leftmask) == 1) {
for
(
int
i = 0; i < n; ++i) {
if
((leftmask & (1 << i)) != 0) {
res = arr[i];
break
;
}
}
}
else
{
res =
int
.MaxValue;
for
(
int
i = 0; i < n; ++i) {
if
((leftmask & (1 << i)) == 0) {
continue
;
}
for
(
int
j = i + 1; j < n; ++j) {
if
((leftmask & (1 << j)) != 0) {
var
val
= Math.Max(arr[i], arr[j]);
val += GFG.findMinTime(
(leftmask ^ (1 << i)
^ (1 << j)),
!turn, arr, n);
res = Math.Min(res, val);
}
}
}
}
}
return
res;
}
public
static
int
findTime(
int
[] arr,
int
n)
{
var
mask = (1 << n) - 1;
for
(
int
i = 0; i < (1 << 20); i++) {
GFG.dp[i, 0] = -1;
GFG.dp[i, 1] = -1;
}
return
GFG.findMinTime(mask,
false
, arr, n);
}
public
static
void
Main(String[] args)
{
int
[] arr = { 10, 20, 30 };
var
n = 3;
Console.Write(GFG.findTime(arr, n));
}
}