zoukankan      html  css  js  c++  java
  • hdu4374One hundred layer (DP+单调队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=4374

    去年多校的题 今年才做 不知道这一年都干嘛去了。。

    DP的思路很好想 dp[i][j] = max(dp[i-1][g]+sum[i][j]-sum[i][g-1],dp[i][j]) abs(g-j)<=t  不过复杂度是相当高的 所以呢 就出现了个单调队列 把它优化下

    所谓的单调队列其实也就是一队列 始终保持着队头是最大的 若满足不了距离的条件 队头+1 队尾始终保持更新 让满足的了距离而且比队里的更大的元素进来

    。。因为一初始化错了  WA了十多次啊 注意:有负数 

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<stdlib.h>
     5 #include<algorithm>
     6 using namespace std;
     7 #define N 105
     8 #define M 10005
     9 #define LL __int64
    10 int a[N][M],que[M];
    11 int dp[N][M];
    12 int s1[N][M],s2[N][M];
    13 int main()
    14 {
    15     int i,j,n,m,x,t,str,end;
    16     while(cin>>n>>m>>x>>t)
    17     {
    18         memset(dp,128,sizeof(dp));
    19         memset(s1,0,sizeof(s1));
    20         memset(s2,0,sizeof(s2));
    21         for(i = 1; i <= n; i++)
    22             for(j = 1; j <= m ; j++)
    23             {
    24                 scanf("%d",&a[i][j]);
    25                 s1[i][j] = s1[i][j-1]+a[i][j];
    26             }
    27         for(i = 1 ; i <= n ;i++)
    28             for(j = m ; j >= 1; j--)
    29             s2[i][j] = s2[i][j+1]+a[i][j];
    30         for(i = x ; i>=1&&i>=x-t ; i--)
    31         dp[1][i] = s1[1][x]-s1[1][i-1];
    32         for(i = x ; i <= m&&i<=x+t ; i++)
    33         dp[1][i] = s2[1][x]-s2[1][i+1];
    34         for(i = 2; i <= n ; i++)
    35         {
    36             str = 0;end=0;
    37             for(j = 1;j <= m ; j++)
    38             {
    39                 while(str<end&&dp[i-1][j]-s1[i][j-1]>dp[i-1][que[end-1]]-s1[i][que[end-1]-1])
    40                 end--;
    41                 que[end++] = j;
    42                 dp[i][j] = max(dp[i][j],dp[i-1][que[str]]-s1[i][que[str]-1]+s1[i][j]);
    43                 if(j-que[str]>=t)
    44                 str++;
    45             }
    46             str = 0;end=0;
    47             for(j = m ; j >= 1; j--)
    48             {
    49                 while(str<end&&dp[i-1][j]-s2[i][j+1]>dp[i-1][que[end-1]]-s2[i][que[end-1]+1])
    50                 end--;
    51                 que[end++] = j;
    52                 dp[i][j] = max(dp[i][j],dp[i-1][que[str]]-s2[i][que[str]+1]+s2[i][j]);
    53                 if(que[str]-j>=t)
    54                 str++;
    55             }
    56         }
    57         int maxz=dp[n][1];
    58         for(i = 1; i <= m ; i++)
    59         maxz = max(maxz,dp[n][i]);
    60         cout<<maxz<<endl;
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    HOJ 2930 Perfect Fill IIl 线性递推
    BZOJ 1269: [AHOI2006]文本编辑器editor Splay
    linux shell常用快捷键(转)
    【引用】Linux date命令
    linux shell if 参数(转)
    vsftpd 530 Permission denied(转)
    捕获非广播包和非发给自己主机的数据包的原理是什么 混杂模式(转)
    代理ARP(转)
    Linux和Unix系统 关系和区别详细介绍(转)
    路由表(转)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3252864.html
Copyright © 2011-2022 走看看