背包问题,开始还以为是分硬币的问题来着。假设一个人将硬币全拿了,领opt[0] = true .从sum开始递推。如果opt[j - A[i] ] = true, 那么opt[j] = true。开始数组开小了,两次RE。记住opt数组开大一些。。
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
const int MAXN = 110;
using namespace std;
int A[MAXN], sum, Case, num;
bool opt[MAXN * 500];
int main ( ) {
cin >> Case;
while ( Case-- ) {
memset ( opt, false, sizeof ( opt ) );
opt[0] = true;
sum = 0;
cin >> num;
for ( int i = 0; i < num; cin >> A[i], sum += A[i], ++i ) ;
for ( int i = 0; i < num; ++i )
for ( int j = sum; j >= A[i]; --j )
if ( opt[j - A[i]] ) opt[j] = true;
int mid;
for ( int i = sum / 2; i >= 0; --i )
if ( opt[i] ) {
mid = i;
break;
}
cout << ( sum - 2 * mid ) << endl;
}
return 0;
}