题目链接~~>
做题感悟:开始做这题时首先想到的是背包,认真优化了一下险过,后来看了学长的博客也可以用搜索过。
解题思路:其实一个深搜就搞定,只是剪枝不好剪枝。
代码:(搜索非本人)
#include <stdio.h> #define max(a,b) a>b?a:b int avg,ans,n,w[21],sum[21]; void dfs(int i=n,int cnt=0)//i为第i个西瓜 cnt为第i个西瓜以后的重量的各种组合 { if(i == 0)//二叉树往下找出所有的cnt,ans为最大的cnt { ans = max(ans,cnt);//找出最大的结果(因为下面的代码保证了结果不会超过平均数,最大结果就是最优解) return ; } if(ans == avg || cnt+sum[i] <= ans) //如果找到平均数或者cnt加上前面所有的西瓜重量都不超过这个最优解, return ; //那么就不用往下算了! if(cnt+w[i] <= avg) dfs(i-1,cnt+w[i]);//要第i个西瓜(如果要了第i个西瓜就超过了平均数,就不要了) dfs(i-1,cnt); //不要第i个西瓜 } int main() { while(~scanf("%d",&n)) { ans = 0; for(int i=1;i<=n;i++)//注意第一个西瓜存在w1里,而不是w0 { scanf("%d",&w[i]); sum[i] = sum[i-1] + w[i];//求出前n项和 } avg = sum[n]/2; //求出平均数 dfs(); //开始遍历,注意要求的是最大的不超过平均数的数 printf("%d\n",sum[n]-2*ans); } return 0; }