训练-总结

这周没怎么做题,临近期末了也开始复习了,所以就没怎么做题,这一周还是主要的做的搜索。
简单地写一写题解吧。

洛谷题解 P1037 [NOIP2002 普及组] 产生数(佛洛依德+高精度)

1120 小木棍

链接:https://www.luogu.com.cn/problem/P1120

题意:

寻找一个最短的木头棍子能够把切成这个数组。

思路:

这个题吧,其实不仅仅是这个题,这个搜索吧,感觉最重要的是找dfs的变量代表的啥意思(真的是太难了,根本想不到)

这个题的主要的思路就是从数组里面的最大值开始遍历,直到遍历到sum/2中,从中找看看有没有能够符合题意的。符合题意得就直接结束循环。exit(0);

怎么根据一个棍的长度看他是否是符合题意的呢?

那么就需要用到dfs了这里面是最难想的,他的代码倒是不是很难理解,就是想不到他的变量。
需要四个变量:
表示这棵树多长、
表示剩下的最大长度、
表示还剩下几棵树、
表示已经拼凑的木棍长度。

剩下的就是对代码进行剪枝了。其实剪枝在写代码的时候就不由而来的就剪完了。

代码如下:

#include <bits/stdc++.h>
using namespace std;
int num[59],maxn=0,minn=100,sum=0;
                                                                  //need表示这棵树多长  // can表示剩下的最大长度
void dfs(int jike,int start,int need,int can){             //jike表示还剩下几棵树 //start表示已经拼凑的木棍长度
    if(jike==0){
        cout<<need<<endl;
        exit(0);}
    if(start==need)
        {dfs(jike-1,0,need,maxn);return ;}
    for(int i=can;i>=minn;i--){
        if(num[i]&&i+start<=need) {
            num[i]--;
            dfs(jike,start+i,need,i);
            num[i]++;
            if(start==0||i+start==need)
                return ;
        }
    }
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) {
        int x;cin>>x;
        if(x<=50){
           num[x]++;
            maxn=max(maxn,x);
            minn=min(minn,x);
            sum+=x;}
   }
        for(int i=maxn;i<=sum/2;i++)
        if(sum%i==0)dfs(sum/i,0,i,maxn);
    cout<<sum<<endl; //如果一条也不对
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晨晓翔同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值