qduoj 分辣条1 (搜索+剪枝)

来源:互联网 发布:我的世界java路径 编辑:程序博客网 时间:2024/06/05 20:47

分辣条

发布时间: 2016年6月26日 20:36   最后更新: 2016年6月26日 20:37   时间限制: 1000ms   内存限制: 128M

“你喝的酸奶是我买的,辣条也是我买的,你现在要跟我分手,你把我当什么?”

“因为你每次分辣条的时候都比我多一根!”

可见分好辣条是一件多么重要的事情。。

现在有n(1<=n<=200)根辣条,每根辣条的重量为a1,a2...ai..an(1<=ai<=100)。

那么能不能把这些辣条分为重量相等的两份呢?

输入有多组数据。 每组数据第一行为一个整数n(1<=n<=200),n代表辣条的数量。 第二行有n个整数,a1,a2...ai..an,其中ai(1<=ai<=100)代表第i根辣条的重量

若能分成重量相等的两份,则输出"YES",否则输出"NO"每个答案占一行

复制
31 2 141 1 1 2
YES

NO

/*

这题和poj2362基本一模一样吧

*/

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 205;int n, a[maxn], avg, maxl, flag;bool book[maxn];void dfs(int num, int cur){    if(flag) return ;    if(num == avg) { flag = 1; return ; }    for(int i = cur; i < n; i++)    {        if(num + a[i] > avg) return ;   //剪枝2,因为有序,到这根时已经过重,更不用说后面的了        if(!book[i] && num+a[i] <= avg)        {            book[i] = 1;            dfs(num+a[i], i+1);            book[i] = 0;            if(flag) return ;   //剪枝3, 一找到就回        }    }}int main(void){    while(cin >> n)    {        memset(book, 0, sizeof(book));        maxl = avg = flag = 0;        for(int i = 0; i < n; i++)        {            scanf("%d", &a[i]);            if(a[i] > maxl) maxl = a[i];            avg += a[i];        }        if(avg % 2 || maxl > avg/2) printf("NO\n");     //剪枝1, 对不能平分和单个辣条过重的进行剪枝        else        {            avg /= 2;            sort(a, a+n);       //便于之后剪枝            dfs(0, 0);            if(flag) printf("YES\n");            else printf("NO\n");        }    }    return 0;}


0 0