• 关于搜索时的优化


    这里拿C++一本通(白书第三版)上DFS的课后题12最佳调度问题举例子。(没看过题去自己翻书)

    这是光盘里附带的标程:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 int n,k,a[101],f[1001],ans;
     6 void find(int x,int y)
     7 {
     8     int i;
     9     if (y>=ans) return;
    10     if (x>n)
    11     {
    12      if (y<ans) ans=y;
    13      return;
    14     }
    15     for(i=1;i<=k;i++)
    16     {
    17      f[i]=f[i]+a[x];
    18      find(x+1,max(y,f[i]));
    19      f[i]=f[i]-a[x];
    20     }
    21 }
    22 int main()
    23 {
    24     int i;
    25     scanf("%d%d",&n,&k);
    26     for(i=1;i<=n;i++)
    27       scanf("%d",&a[i]);
    28     memset(f,0,sizeof(f));
    29     ans=2147483647;
    30     find(1,0);
    31     printf("%d",ans);
    32 }

    然后我们拿一组附带的测试数据:

    in

    19 4
    21 60 24 44 81 71 42 9 51 56 41 79 23 60 85 86 72 10 15

    out 

    233

    就发现标程T了= =

    我们改一改标程,加上点玄学优化:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 int n,k,a[101],f[1001],ans;
     6 void find(int x,int y)
     7 {
     8     int i;
     9     if (y>=ans) return;
    10     if (x>n)
    11     {
    12      if (y<ans) ans=y;
    13      return;
    14     }
    15     for(i=1;i<=k;i++)
    16     {
    17      f[i]=f[i]+a[x];
    18      find(x+1,max(y,f[i]));
    19      f[i]=f[i]-a[x];
    20     }
    21 }
    22 int main()
    23 {
    24     int i;
    25     scanf("%d%d",&n,&k);
    26     for(i=1;i<=n;i++)
    27       scanf("%d",&a[i]);
    28     sort(a+1,a+1+n);
    29     reverse(a+1,a+1+n);
    30     memset(f,0,sizeof(f));
    31     ans=2147483647;
    32     find(1,0);
    33     printf("%d",ans);
    34 }

    相比标程,改动后的程序只在28,29两行加了个sort排序并且反了过来。(reverse是把数组里的元素改成逆序,就是把sort排完序的从小到大改成从大到小,你写个自定义比较函数也OK)

    然后= =神奇的事情就发生了,跑的比标程快多了2333。

    对于搜索的优化,除了对初始数据进行排序(从大到小和从小到大的结果是不一样的,比如这个题如果你是按从小到大排再搜索依旧是TLE),还可以在搜索前进行一次贪心,先认为你的贪心结果是对的,这样的话就算贪到的结果不是正解,也比较接近正解,这样在搜索的时候比你贪到的答案大的就可以直接跳过了。(当然你要考虑你贪心的时间复杂度,不要贪来贪去贪的慢。)

    隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。

    隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。

  • 相关阅读:
    堆和栈的区别
    MyKTV点歌系统
    KTV音乐播放的实现
    继承与多态之汽车租赁系统
    使用集合组织相关数据
    用户登陆及异常的处理
    oracle函数详解
    Java中的多线程
    JAVA Map集合框架的使用
    Java中迭代器初深
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/8520967.html
Copyright © 2020-2023  润新知