• 可爱精灵宝贝(贪心,搜索)


    带有贪心思想的搜索,

    我们很容易想到,对于自身来说,如果L---R区间已经走过,那么在最优策略下不会重复走

    同时,每次我们都会找离本节点最近的点&&符合条件移动,

    (假设我们当前不走,那么我们走到其他点才返回一定不优)

    那么我们搜索的时间复杂度最大为2^100,又因为剪枝(L,R距离剪枝),是能水掉的啦啦啦...

    当然用DP做也行,我考试为啥要打状压????????????

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<set>
     8 #include<vector>
     9 #include<map>
    10 #include<queue>
    11 #define MAXN 6101
    12 #define int long long
    13 using namespace std;
    14 int a[MAXN],b[MAXN],t[MAXN];
    15 int dis[MAXN][MAXN];
    16 int n,k,m;
    17 int sum=0;
    18 void find(int pos,int l,int r,int time,int ans)
    19 {
    20      sum=max(ans,sum);
    21      if(time>2000)return ;
    22      //printf("pos=%lld l=%lld r=%lld time=%lld ans=%lld
    ",pos,l,r,time,ans);
    23      for(int i=pos-1;i>=1;--i)
    24      {
    25          if(a[i]>=l&&a[i]<=r)continue;
    26          if(dis[pos][i]+time>t[i])continue;
    27          find(i,min(a[i],l),max(r,a[i]),time+dis[pos][i],ans+b[i]);
    28          break;
    29      }
    30      for(int i=pos+1;i<=m;++i)
    31      {
    32          if(a[i]>=l&&a[i]<=r)continue;
    33          if(dis[pos][i]+time>t[i])continue;
    34          find(i,min(l,a[i]),max(a[i],r),time+dis[pos][i],ans+b[i]);
    35          break;
    36      }
    37      return ;
    38 }
    39 signed main()
    40 {
    41      scanf("%lld%lld%lld",&n,&k,&m);
    42      for(int i=1;i<=m;++i)
    43      {
    44          scanf("%lld%lld%lld",&a[i],&b[i],&t[i]);
    45      }
    46      for(int i=1;i<=m;++i)
    47      {
    48          for(int j=1;j<=m;++j)
    49          {
    50               dis[i][j]=abs(a[i]-a[j]);
    51          }
    52      }
    53      int l=0,r=0;
    54      for(int i=1;i<=m;++i)
    55      if(a[i]<=k&&abs(a[i]-k)+1<=t[i])l=i;  
    56      for(int i=m;i>=1;--i)
    57      if(a[i]>=k&&abs(a[i]-k)+1<=t[i])r=i;
    58      if(l!=0)
    59      find(l,min(a[l],k),max(a[l],k),abs(a[l]-k)+1,b[l]);
    60      if(r!=0)
    61      find(r,min(a[r],k),max(a[r],k),abs(a[r]-k)+1,b[r]);     
    62      printf("%lld
    ",sum);
    63 }
    View Code
  • 相关阅读:
    【题解】【HDU 3487】Play with Chain
    学习+复习目标
    【题解】【NOIP2018PJ】对称二叉树
    NOIP2018复赛游记
    论蒟蒻的作死程度
    教你如何不用新分区添加swap
    云主机的极致优化
    Linux权限管理 特殊权限解析
    用户组管理
    vim编辑器详解
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11342655.html
Copyright © 2020-2023  润新知