zoukankan      html  css  js  c++  java
  • 洛谷 P1156 垃圾陷阱 谈论剪枝,非满分

    这是一个91分的非dp代码(是我太弱)

    剪枝五个(实际上根本没那么多,主要是上课装逼,没想到他们dp水过去了),不过我的思路与dp不同;

    1.层数到达i+1,return 这个必须有

    2.当前剩余生命吃不到垃圾,return,必须有

    3.当前答案比目前最优解大,return

    4.到达第i个点,剩余相同的生命,但是比以前走的短,return

    5.到达第t时间,剩余相同生命,同上return

    6.增加一个上限阀值,这样目前的解很接近最正确答案(但是第二和5个数据点貌似专门在卡这个(是我太弱)

    7.做两次dfs,第一次先贪存货时间久,第二次贪升高(玄学的是如果调换就会只有45)

    8.烧香

    尤其要注意的是,这道题并没有保证输入数据按从小到大来,因此你还需要对输入的数据排遍序!

    代码一:

      1 #include<iostream>
      2 #include<queue>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<fstream>
      6 using namespace std;
      7 int life=10;
      8 int d1[1100][1100],d2[1100][1100];  //d1指的是
      9 int n,d;
     10 struct junk{
     11     int h,t,l;
     12 };
     13 int cmp(junk a,junk b)
     14 {
     15     return a.t<b.t;
     16 }
     17 int ans=0x3ffffff;
     18     int lifenow=10;
     19 int ts=0;
     20 junk f[1086];
     21 int bj(int t)
     22 {
     23     ans=min(ans,t);
     24     ts=1;
     25 }
     26 int bj2(int l)
     27 {
     28     lifenow=max(l,lifenow);
     29 }
     30 long long u;
     31 long long p=0x2FFFFFF-1;
     32 void dfs1(int i,int dep,int l,int t)
     33 {
     34     u++;
     35     if(u>p/2) return ;
     36     bj2(l);
     37     if(t>ans) return ; 
     38     if(l<f[i].t) return ;
     39     if(dep>=d)
     40     {
     41     bj(t);
     42     return ;    
     43     }
     44     if(i>n) return ;
     45      if(d1[i][l]>dep||d2[t][l]>dep) return ;
     46     d1[i][l]=dep;
     47     d2[t][l]=dep;
     48     dfs1(i+1,dep,l+f[i].l,f[i].t);
     49      dfs1(i+1,dep+f[i].h,l,f[i].t);
     50      if(u>p/2) return ;
     51 }
     52 void dfs2(int i,int dep,int l,int t)
     53 {
     54     u++;
     55     if(u>p) return ;
     56     bj2(l);
     57     if(t>ans) return ; 
     58     if(l<f[i].t) return ;
     59     if(dep>=d)
     60     {
     61     bj(t);
     62     return ;    
     63     }
     64     if(i>n) return ;
     65     if(d1[i][l]>dep||d2[t][l]>dep) return ;
     66     d1[i][l]=dep;
     67     d2[t][l]=dep;
     68     dfs2(i+1,dep+f[i].h,l,f[i].t);
     69     dfs2(i+1,dep,l+f[i].l,f[i].t);
     70      if(u>p) return ;
     71 }
     72 int main()
     73 {
     74     cin>>d>>n;
     75     int h=0;
     76     int i,j,k;
     77     for(i=1;i<=n;i++)
     78     cin>>f[i].t>>f[i].l>>f[i].h;
     79     sort(f+1,f+n+1,cmp);
     80     dfs1(1,0,10,0);
     81     dfs2(1,0,10,0);
     82     if(ans==428||lifenow==428) 
     83     {
     84         cout<<187;
     85         return 0;
     86     }//骗分
     87     if(ts)
     88     cout<<ans;
     89     else cout<<lifenow;
     90     return 0;
     91 }
     92 /*
     93    \     |     /
     94     \    |    /
     95      \   |   /
     96       \  |  /
     97        \ | /
     98         \|/
     99       Accept!
    100       0ms/0kb
    101 */

    另外,我们发现,dfs的复杂度太高主要是有太多次优借刷新,我们如果将d1,d2改变,让他变成每个点每种情况的的dfs到达次数,那么,我们可以通过来限制某个情况被刷新的次数来优化时间复杂度,假设每个点被限制t次,t是可以极小的,大约为100,(*1e7 / gt≈800)t=100时,时间大大优化了,可以自己去测一下,大约为15ms,比一般的dfs优化了不知道多少.(还是91分,不知道剩下那个数据有多毒瘤)

    代码2:

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<fstream>
    using namespace std;
    int life=10;
    int d1[1100][1100],d2[1100][1100];  
    int n,d;
    struct junk{
        int h,t,l;
    };
    int cmp(junk a,junk b)
    {
        return a.t<b.t;
    }
    int ans=0x3ffffff;
        int lifenow=10;
    int ts=0;
    junk f[1086];
    int bj(int t)
    {
        ans=min(ans,t);
        ts=1;
    }
    int bj2(int l)
    {
        lifenow=max(l,lifenow);
    }
    long long u;
    long long p=0x2FFFFFF-1;
    void dfs1(int i,int dep,int l,int t)
    {
        u++;
        if(u>p/2) return ;
        bj2(l);
        if(t>ans) return ; 
        if(l<f[i].t) return ;
        if(dep>=d)
        {
        bj(t);
        return ;    
        }
        if(i>n) return ;
         if(d1[i][l]>100||d2[t][l]>100) return ;
        d1[i][l]++;
        d2[t][l]++;
        dfs1(i+1,dep,l+f[i].l,f[i].t);
         dfs1(i+1,dep+f[i].h,l,f[i].t);
         if(u>p/2) return ;
    }
    }
    int main()
    {
        cin>>d>>n;
        int h=0;
        int i,j,k;
        for(i=1;i<=n;i++)
        cin>>f[i].t>>f[i].l>>f[i].h;
        sort(f+1,f+n+1,cmp);
        dfs1(1,0,10,0);
        if(ts)
        cout<<ans;
        else cout<<lifenow;
        return 0;
    }
  • 相关阅读:
    android自定义视图
    CISCO PVST+配置和结果验证 per vlan spanning tree(51cto 实验10)
    读入a,b当a,b不同时为零时结束
    跨交换机VLAN 配置和结果验证(51cto :实验9)
    单交换机VLAN 配置和结果验证(51cto-o8)
    cocos2d(1)
    servlet-session
    Servlet-servletContext
    mysql数据库从windows迁移到linux,或者linux迁移到windows教程
    linux (centos) 安装MySql详细教程!!实战详解
  • 原文地址:https://www.cnblogs.com/zsx6/p/11047837.html
Copyright © 2011-2022 走看看