NYOJ 325 zb的生日

题目链接~~>

做题感悟:开始做这题时首先想到的是背包,认真优化了一下险过,后来看了学长的博客也可以用搜索过。

解题思路:其实一个深搜就搞定,只是剪枝不好剪枝。

代码:(搜索非本人)

#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;  
}                  


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值