zoukankan      html  css  js  c++  java
  • 【洛谷习题】小木棍[数据加强版]

    题目链接:https://www.luogu.org/problemnew/show/P1120


    算起来,这道题在我初涉OI后没几个月就强化了数据,之前版本的就没机会做了。。。

    很好的一道题,可以学到很多东西。不管是做题技巧上的,代码能力上的,还是剪枝方法上的。

    搜索题的话,现在觉得不要一上去就写个能过的代码,先写个裸暴力,再一步步优化。

    然后学到了一个技巧,对于调用了很多层DFS后,找到了答案,可以直接输出然后用exit(0)退出程序,常数会小一点。

    一开始这道题我连个暴力都不会写,做题少了,思维太局限,老是想着搜索每根木棍取还是不取,比较好的方法是搜索拼接了几根大木棍,当前在拼的还差多少。

    然后重点说一下剪枝优化。这里放一句大佬的话,“其实剪枝没有那么多标准,关键在于,你的那个判断只要可以减少搜索一些无用的情况即可,同时还要保证不会把合法的答案也剪去。”

    1、我们的搜索是先枚举一个最小长度,然后搜索是否可行。显然可以从小到大枚举,一旦验证成功就代表找到了答案。并且,这个最小长度一定比最长的小木棍长,还是小木棍长度和的因数。还有一个小优化,我们枚举时,枚举到sum/2即可,若一直未找到答案,说明答案就是sum。

    2、短的小木棍比长的小木棍灵活,所以要放到后面用,大家都这么说。其实就是优化搜索顺序,减少不必要的情况。所以可以先将小木棍从长到短排序。搜索时,如果使用了一根小木棍,那么下一根不能更长。

    3、如果选择一根木棍继续搜索失败了,那么替换时,不能选择长度相等的,因为长度相等的木棍是等效的。

    4、如果选择了一根木棍继续搜索失败了,此时已拼接的长度为0,则返回上一层,因为这说明当前木棍无法与剩下的任何几根木棍拼成大木棍,再搜下去也不会成功;同样,若此时拼成大木棍所需剩余长度恰好等于当前小木棍长度,即当前小木棍不与剩下的其他木棍拼在一起,那么再搜下去也不会成功了,即使他可以被若干根更短木棍代替(等效)。

    加上这些优化,就可以在较短的时间内通过这道题了。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=70;
     5 int n,l[maxn],sum,ml,vis[maxn];
     6 int ncnt,len;
     7 void dfs(int cnt,int rest,int no) {
     8     if(cnt==ncnt) {printf("%d",len);exit(0);}
     9     for(int i=no;i<=n;++i) if(!vis[i])
    10         if(l[i]<=rest) {
    11             vis[i]=1;
    12             if(l[i]<rest) dfs(cnt,rest-l[i],i+1);
    13             else dfs(cnt+1,len,1);
    14             vis[i]=0;
    15             while(l[i]==l[i+1]) ++i;
    16             if(rest==len||rest-l[i]==0) return;
    17         }
    18 }
    19 bool comp(int a,int b) {return a>b;}
    20 int main() {
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;++i) {
    23         scanf("%d",&l[i]);
    24         if(l[i]>50) {--i,--n;continue;}
    25         sum+=l[i];ml=max(ml,l[i]);
    26     }
    27     sort(l+1,l+n+1,comp);
    28     for(int i=ml;i<=sum/2;++i) if(sum%i==0) {
    29         len=i,ncnt=sum/len;
    30         dfs(0,len,1);
    31     }
    32     printf("%d",sum);
    33     return 0;
    34 }
    AC代码
  • 相关阅读:
    HDU
    2015 NCPC Problem G-Goblin Garden Guards
    二分答案
    多校 HDU-6312 Game (博弈)
    唯一分解定理
    欧拉函数
    发布系统遇到的问题解决
    ASP.Net数据导出Excel的几种方法
    项目管理计划书模版
    sql server2008附加数据库5120错误
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9709103.html
Copyright © 2011-2022 走看看