HDU 3765 Celebrity Split(dfs走平分问题--递推)

Problem Description
Jack and Jill have decided to separate and divide their property equally. Each of their N mansions has a value between 1,000,000 and 40,000,000 dollars. Jack will receive some of the mansions; Jill will receive some of the mansions; the remaining mansions will be sold, and the proceeds split equally.

Neither Jack nor Jill can tolerate the other receiving property with higher total value. The sum of the values of the mansions Jack receives must be equal to the sum of the values of the mansions Jill receives. So long as the value that each receives is equal, Jack and Jill would like each to receive property of the highest possible value.

Given the values of N mansions, compute the value of the mansions that must be sold so that the rest may be divided so as to satisfy Jack and Jill.
 

Input
The input consists of a sequence of test cases. The first line of each test case contains a single integer N, the number of mansions, which will be no more than 20. This line is followed by N lines, each giving the value of a mansion. The final line of input contains the integer zero. This line is not a test case and should not be processed.
 

Output
For each test case, output a line containing a single integer, the value of the mansions that must be sold so that the rest may be divided so as to satisfy Jack and Jill.
 

Sample Input
 
   
5 6000000 30000000 3000000 11000000 3000000 0
 

Sample Output
 
   
41000000
 

//Must so
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,x) memset(a,x,sizeof(a))
#define inf 1<<30
#define NN 1000006
using namespace std;
const double PI = acos(-1.0);
typedef long long LL;
/**********************************************************************
题意:
n件物品各有价格vi,两个人分这些物品,要使每人分得的总价值相等,不能
满足要求的物品拿去卖再分,问拿去卖的物品的最小总价值
思路:
n不超过20,暴力+剪枝应该可行,
每个物品要么给A要么给B要么拿去卖
...只能说数据太弱,没有剪枝的居然就A了,于是懒得再剪枝了
**********************************************************************/
int sun[33];//记录前i件房子的种价格
int moon ;//记录两人分走的物品的价值
int n;//n件物品
int a[33];//记录每件物品的价值
void div(int p,int A,int B)//p是当前要分的房子的编号,A是A拿走的价值,B是B拿走的价值
{
    if (p > n) return;
    if (A == B)//可以平分价值
    {
        if (A+B > moon) moon = A+B;
    }
    div(p+1,A,B);//拿去卖
    div(p+1,A+a[p],B);//给A
    div(p+1,A,B+a[p]);//给B
}
int main()
{
    while (cin>>n)
    {
        if (!n) break;
        for (int i = 0;i < n;i++)
            scanf("%d",&a[i]);
            sun[0] = a[0];
        for (int i = 1;i < n;i++)
            sun[i] = sun[i-1] + a[i];
        moon = 0;
        div(0,0,0);
        printf("%d\n",sun[n-1]-moon);
    }
    return 0;
}

你可能感兴趣的:(ACM题解与算法,ACM(算法))