zoukankan      html  css  js  c++  java
  • [bzoj1915] [Usaco2010 Open]奶牛的跳格子游戏

      dp+单调队列优化TAT。。一开始有个条件没细想结果方程推错了TAT。

      主要是转移的时候强制留下哪个点作为回去的落脚点的问题= =。。

      预处理出presum[i]表示1~i个格子中,正数的前缀和(因为在K的小范围内肯定会贪心地选正数的点跳),val[i]表示第i个格子上的数字。

      f[i]表示当前跳到第i个格子,并且留下了一条回去的路的最大总和。

      f[i]=max{ f[j]+presum[i-1]-presum[j] }+val[i-1]+val[i],(i-K<=j<i-1)

        也就是从j跳到i,并且强制(i-1)不走,留作回去的路(但回来的时候一定会走的。。所以先把val[i-1]加上)。

      max{f[i]}并不是最后的答案。。因为对于f[i],我们留下了(i-1)作回去时的第一个点。。所以还可以走完 [i+1,i-1+K]这些点中的正数点 再跳回(i-1)。。。注意边界

      一开始太懒。不想算最后多走一段的情况。。所以不是强制i-1不走,而是强制j+1不走。。。结果贪心地取[j+2,i]中的点时可能使j+2走不到。。

      而如果强制j-1不走的话会重复计算。。。所以还是只能强制i-1不走。。。然而这样就会产生走到i后可以多走一段的情况TAT

    幸好速度#1弥补了我心灵的创伤(大雾

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=250233;
     7 ll f[maxn],presum[maxn],ans,dl[maxn];
     8 int val[maxn],dlpos[maxn];
     9 int i,j,n,m,K,l,r;
    10 int ra,fh;char rx;
    11 inline int read(){
    12     rx=getchar();ra=0;fh=1;
    13     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    14     if(rx=='-')fh=-1,rx=getchar();
    15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
    16 }
    17 int main(){
    18     n=read();K=read();n++;
    19     for(i=2;i<=n;i++)val[i]=read(),presum[i]=presum[i-1]+(ll)(val[i]>0?val[i]:0);//,printf("              %d %lld
    ",val[i],presum[i]);
    20     f[0]=f[1]=0;
    21     l=1;r=0;
    22     ll tmp;
    23     for(i=2,j=0;i<=n;i++,j++){
    24         tmp=f[j]-presum[j];
    25         while(l<=r&&dl[r]<=tmp)r--;dl[++r]=tmp;dlpos[r]=j;
    26         while(l<r&&dlpos[l]<i-K)l++;
    27 //      for(int k=l;k<=r;k++)printf("   %lld %d",dl[k],dlpos[k]);printf("
    ");
    28         f[i]=dl[l]+presum[i-2]+val[i-1]+val[i];
    29 //      printf("%d   %lld
    ",i,f[i]);
    30     }
    31     ans=f[1]+presum[min(1+K,n)];
    32     for(i=2;i<=n;i++){
    33         f[i]+=(i+K-1<=n)?(presum[i+K-1]-presum[i]):(presum[n]-presum[i]);
    34         if(f[i]>ans)ans=f[i];
    35     }
    36     printf("%lld
    ",ans);
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    js 实现加入收藏/加入首页功能
    js 获取网页宽/高度
    js 飞机大战
    js 实现分享功能
    前端开发的工具,库和资源总结
    网站更新后客户端缓存问题
    js 实现图片无限横向滚动效果
    js 实现 文字打印效果
    js 构造函数创建钟表
    Css3 实现关键帧动画
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5084120.html
Copyright © 2011-2022 走看看