This is really classic searching problem to solve. The key is pruning.
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-YWan5iNwgDNmBjM2E2NkhjYhFzMmdTN4QWM4kTZxIWMhFWMx8CX0EzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL2M3Lc9CX6MHc0RHaiojIsJye.gif)
// 1011
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define MAX_STICK 64
bool cmp (int i,int j) { return (i > j); }
bool dfs(int *sticks, bool *visited, int currLen, int tgtLen, int currInx, int usedCnt, int n)
{
if(usedCnt == n) return true;
int skipLen = -1;
for(int i = currInx; i < n; i ++ )
{
if(visited[i] || sticks[i] == skipLen) continue; // Pruning 3: if that len needs to be skipped
visited[i] = true;
int currCmb = currLen + sticks[i];
if(currCmb < tgtLen)
{
if(dfs(sticks, visited, currCmb, tgtLen, i, usedCnt + 1, n))
return true;
else
skipLen = sticks[i];
}
else if(currCmb == tgtLen)
{
if(dfs(sticks, visited, 0, tgtLen, 0, usedCnt + 1, n))
return true;
else
skipLen = sticks[i];
}
visited[i] = false;
if(currLen == 0) break; // Pruning 4: for starting point 0, no matches then NO
// * it makes TLE passing as 16MS
}
return false;
}
int main()
{
int n;
while (scanf("%d", &n), n != 0)
{
int sticks[MAX_STICK] = { 0 };
bool visited[MAX_STICK] = { false };
// Input
int sum = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d", sticks + i);
sum += sticks[i];
}
// Sort descending
sort (sticks, sticks + n, cmp);
// Searching by pruning
bool bFound = false;
for(int l = sticks[0]; l <= sum - l; l ++) // Pruning 1
{
if( (sum % l == 0) && dfs(sticks, visited, 0, l, 0, 0, n)) // Pruning 2
{
bFound = true;
printf("%d\n", l);
break;
}
}
if(!bFound) printf("%d\n", sum);
}
return 0;
}
View Code