/* package whatever; // don't place package name! */
import java.util.* ;
import java.lang.* ;
import java.io.* ;
import java.util.Arrays ;
class Ideone {
static int max = 0 ;
public static void main
( String [ ] args
) { // TODO Auto-generated method stub
for ( int N= 1 ; N<= 50 ; N++ ) {
int [ ] elem = new int [ N] ;
for ( int i= 1 ; i<= N; i++ ) {
elem[ i- 1 ] = rand.nextInt ( 999 ) + 1 ;
}
max = 0 ;
//System.out.println(Arrays.toString(elem));
long start
= System .
currentTimeMillis ( ) ;
int maxHeight = getMaxHeight( elem) ;
long end
= System .
currentTimeMillis ( ) ; System .
out .
println ( N
+ "==>" + maxHeight
+ " Time Taken=" + ( end
- start
) / 1000 + "\n \n " ) ;
}
}
private static int getMaxHeight( int [ ] elem) {
// TODO Auto-generated method stub
boolean [ ] table = new boolean [ elem.length ] ;
int sum = 0 ;
int [ ] sumTable = new int [ elem.length ] ;
for ( int i= 0 ; i< elem.length ; i++ ) {
sum += elem[ i] ;
sumTable[ i] = sum;
}
int max = getMaxComb( elem,0 ,0 ,sum/ 2 ,table,sumTable) ;
return max;
}
private static int getMaxComb( int [ ] arr, int start, int sum, int half, boolean [ ] table, int [ ] sumTable) {
// TODO Auto-generated method stub
if ( start== arr.length || sum> half || ( sum+ sumTable[ start] ) < max ) {
if ( sum<= half && sum> max && isOtherSumPossible( arr,sum,table) ) {
return sum;
}
return 0 ;
}
table[ start] = true ;
int x = getMaxComb( arr , start+ 1 , arr[ start] + sum, half,table, sumTable) ;
if ( max< x)
max = x;
table[ start] = false ;
int y = getMaxComb( arr, start+ 1 , sum, half,table, sumTable) ;
if ( max< y)
max = y;
return x> y? x: y;
}
private static boolean isOtherSumPossible( int [ ] arr, int sum, boolean [ ] table) {
// TODO Auto-generated method stub
if ( sum == 0 || arr.length == 0 )
return true ;
int count = 0 ;
for ( boolean x : table) {
count = x== false ? count+ 1 : count;
}
int [ ] data = new int [ count+ 1 ] ;
for ( int i= 0 , j= 1 ; i< arr.length ; i++ ) {
if ( ! table[ i] ) {
data[ j] = arr[ i] ;
j++;
}
}
boolean [ ] [ ] dp = new boolean [ data.length ] [ sum+ 1 ] ;
for ( int i= 0 ; i< dp.length ; i++ ) {
dp[ i] [ 0 ] = true ;
}
for ( int i= 1 ; i< dp.length ; i++ ) {
for ( int j= 1 ; j< dp[ 0 ] .length ; j++ ) {
if ( j< data[ i] ) {
dp[ i] [ j] = dp[ i- 1 ] [ j] ;
} else {
dp[ i] [ j] = dp[ i- 1 ] [ j- data[ i] ] ;
}
}
}
return dp[ dp.length - 1 ] [ dp[ 0 ] .length - 1 ] ;
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgppbXBvcnQgamF2YS51dGlsLkFycmF5czsKCiBjbGFzcyBJZGVvbmUgewoKCXN0YXRpYyBpbnQgbWF4ID0gMDsKCQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCQlSYW5kb20gcmFuZCA9IG5ldyBSYW5kb20oKTsKCQlmb3IoaW50IE49MTsgTjw9NTA7IE4rKykgewoKCQkJaW50IFtdIGVsZW0gPSBuZXcgaW50W05dOwoJCQlmb3IoaW50IGk9MTsgaTw9TjsgaSsrKSB7CgkJCQllbGVtW2ktMV0gPSByYW5kLm5leHRJbnQoOTk5KSsxOwoJCQl9CgkJCW1heCA9IDA7CgkJCS8vU3lzdGVtLm91dC5wcmludGxuKEFycmF5cy50b1N0cmluZyhlbGVtKSk7CgkJCWxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCQkJCgkJCWludCBtYXhIZWlnaHQgPSBnZXRNYXhIZWlnaHQoZWxlbSk7CgoJCQlsb25nIGVuZCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCQlTeXN0ZW0ub3V0LnByaW50bG4oTisiPT0+IittYXhIZWlnaHQgKyIgVGltZSBUYWtlbj0iKyhlbmQtc3RhcnQpLzEwMDArIlxuXG4iKTsKCQkJCgkJfQoKCX0KCglwcml2YXRlIHN0YXRpYyBpbnQgZ2V0TWF4SGVpZ2h0KGludFtdIGVsZW0pIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJCgkJYm9vbGVhbiBbXSB0YWJsZSA9IG5ldyBib29sZWFuW2VsZW0ubGVuZ3RoXTsKCQkKCQlpbnQgc3VtID0gMDsKCQoJCWludCBbXSBzdW1UYWJsZSA9IG5ldyBpbnRbZWxlbS5sZW5ndGhdOwoJCQoJCWZvcihpbnQgaT0wO2k8ZWxlbS5sZW5ndGg7IGkrKykgewoJCQlzdW0gKz0gZWxlbVtpXTsKCQkJc3VtVGFibGVbaV0gPSBzdW07CgkJfQoJCQoJCQoJCWludCBtYXggPSBnZXRNYXhDb21iKGVsZW0sMCwwLHN1bS8yLHRhYmxlLHN1bVRhYmxlKTsKCQkKCQlyZXR1cm4gbWF4OwoJfQoKCXByaXZhdGUgc3RhdGljIGludCBnZXRNYXhDb21iKGludFtdIGFyciwgaW50IHN0YXJ0LCBpbnQgc3VtLCBpbnQgaGFsZiwgYm9vbGVhbltdIHRhYmxlLCBpbnQgW10gc3VtVGFibGUpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJCgkJaWYoc3RhcnQ9PWFyci5sZW5ndGggfHwgc3VtPmhhbGYgfHwgKHN1bStzdW1UYWJsZVtzdGFydF0pPCBtYXggKSB7CgkJCQoJCSBpZihzdW08PWhhbGYgJiYgc3VtPm1heCAmJiBpc090aGVyU3VtUG9zc2libGUoYXJyLHN1bSx0YWJsZSkpIHsKCQkJIHJldHVybiBzdW07CgkJIH0KCgkJICByZXR1cm4gMDsKCQl9CgkJCgkJCgkJCgkJdGFibGVbc3RhcnRdID0gdHJ1ZTsKCQkKCQlpbnQgeCA9IGdldE1heENvbWIoIGFyciAsIHN0YXJ0KzEsIGFycltzdGFydF0rc3VtLCBoYWxmLHRhYmxlLCBzdW1UYWJsZSk7CgkJCgkJaWYobWF4PHgpCgkJCW1heCA9IHg7CgkJCgkJdGFibGVbc3RhcnRdID0gZmFsc2U7CgkJCgkJaW50IHkgPSBnZXRNYXhDb21iKCBhcnIsICBzdGFydCsxLCAgc3VtLCBoYWxmLHRhYmxlLCBzdW1UYWJsZSk7CgoJCWlmKG1heDx5KQoJCQltYXggPSB5OwoJCQoJCXJldHVybiB4Pnk/eDp5OwoJfQoKCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNPdGhlclN1bVBvc3NpYmxlKGludFtdIGFyciwgaW50IHN1bSwgYm9vbGVhbiBbXSB0YWJsZSkgewoJCS8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgbWV0aG9kIHN0dWIKCgkJCgkJaWYoc3VtID09IDAgfHwgYXJyLmxlbmd0aCA9PSAwKQoJCQlyZXR1cm4gdHJ1ZTsKCQkKCQkKCQlpbnQgY291bnQgPSAwOwoJCWZvcihib29sZWFuIHggOiB0YWJsZSkgewoJCQkKCQkJY291bnQgPSB4PT1mYWxzZT9jb3VudCsxOmNvdW50OwoJCX0KCQkKCQlpbnQgW10gZGF0YSA9IG5ldyBpbnRbY291bnQrMV07CgoJCWZvcihpbnQgaT0wLCBqPTE7IGk8YXJyLmxlbmd0aDsgaSsrKSB7CgkJICAgIAoJCQlpZighdGFibGVbaV0pIHsKCQkgICAgCWRhdGFbal09YXJyW2ldOwoJCSAgICAJaisrOwoJCSAgICB9CgkJCQoJCX0KCQkKCQoJCQoJCWJvb2xlYW4gW11bXSBkcCA9IG5ldyBib29sZWFuW2RhdGEubGVuZ3RoXVtzdW0rMV07CgkJZm9yKGludCBpPTA7IGk8ZHAubGVuZ3RoOyBpKyspIHsKCQkJZHBbaV1bMF09dHJ1ZTsKCQl9CgkJCgkJZm9yKGludCBpPTE7IGk8ZHAubGVuZ3RoOyBpKyspIHsKCQkJCgkJCWZvcihpbnQgaj0xOyBqPGRwWzBdLmxlbmd0aDsgaisrKSB7CgkJCQkKCQkJCWlmKGo8ZGF0YVtpXSkgewoJCQkJCgkJCQkJZHBbaV1bal0gPSBkcFtpLTFdW2pdOwoJCQkJCgkJCQl9ZWxzZSB7CgkJCQkJCgkJCQkJZHBbaV1bal0gPSBkcFtpLTFdW2otZGF0YVtpXV07CgkJCQl9CQoJCQl9CQoJCX0KCgkJcmV0dXJuIGRwW2RwLmxlbmd0aC0xXVtkcFswXS5sZW5ndGgtMV07Cgl9Cgp9