zoukankan      html  css  js  c++  java
  • hdu 4374 (单调队列+dp)

    d[i][j]表示i行j列格子可以得到的最大值

    顺着来的时候

    d[i][j]=max(d[i-1][k]+sum[k...j])=max(d[i-1][k]-sum[1..k-1]+sum[1...j])  sum[1...j]是固定值 只要找d[i-1][k]+sum[1...k]  的最大值就可以了

    找法就是维护一个单调递减的队列,每次加入一个值进去就把队列值后面小于它的点都删掉,把前面j-k>t的点删掉(走的步数大于t步),d[i][j]=队首值+sum[1...j]

    逆着来的时候

    d[i][j]=max(d[i-1][k]+sum[k...j])=max(d[i-1][k]+sum[1...k])-sum[1...j-1]  sum[1...k]是固定值 只要找d[i-1][k]-sum[1...j]  的最大值就可以了

    维护一个单调递减的队列,每次加入一个值进去就把队列值后面小于它的点都删掉,把前面j-k>t的点删掉(走的步数大于t步),d[i][j]=队首值-sum[1...k]

     1 #include<iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 #include<queue>
     5 using namespace std;
     6 #define INF -9999999
     7 int a[102][10002],d[102][10002],sum[102][10002];
     8 
     9 struct node
    10 {
    11     int zhi,wei;
    12 } q[10002];
    13 
    14 
    15 int main()
    16 {
    17     int k,n,m,x,t;
    18     while(~scanf("%d%d%d%d",&n,&m,&x,&t))
    19     {
    20         for(int i=1; i<=n; i++)
    21             for(int j=1; j<=m; j++)
    22                 scanf("%d",&a[i][j]);
    23         for(int i=1; i<=n; i++)
    24             for(int j=1; j<=m; j++)
    25                 d[i][j]=INF;
    26         memset(sum,0,sizeof(sum));
    27         d[1][x]=a[1][x];
    28         for(int i=1; i<=t&&i+x<=m; i++)
    29             d[1][i+x]=max(d[1][x+i],d[1][x+i-1]+a[1][x+i]);
    30 
    31         for(int i=1; i<=t&&x-i>=1; i++)
    32             d[1][x-i]=max(d[1][x-i],d[1][x-i+1]+a[1][x-i]);
    33 
    34         for(int i=2; i<=n; i++)
    35         {
    36             for(int j=1; j<=m; j++)
    37                 sum[i][j]=sum[i][j-1]+a[i][j];
    38 
    39             int front1=0,rear=0;
    40             for(int j=1; j<=m; j++)
    41             {
    42 
    43                 int temp=d[i-1][j]-sum[i][j-1];
    44                 while(front1<rear&&q[rear-1].zhi<temp)
    45                     rear--;
    46                 q[rear].zhi=temp;
    47                 q[rear++].wei=j;
    48 
    49                 while(front1<rear&&j-q[front1].wei>t)
    50                     front1++;
    51 
    52                 d[i][j]=max(d[i][j],q[front1].zhi+sum[i][j]);
    53 
    54             }
    55             front1=0,rear=0;
    56             for(int j=m; j>=1; j--)
    57             {
    58                 int temp=d[i-1][j]+sum[i][j];
    59                 while(q[rear-1].zhi<temp&&front1<rear)
    60                     rear--;
    61                 q[rear].zhi=temp;
    62                 q[rear++].wei=j;
    63 
    64                 while(front1<rear&&q[front1].wei-j>t)
    65                     front1++;
    66                 d[i][j]=max(d[i][j],q[front1].zhi-sum[i][j-1]);
    67             }
    68 
    69         }
    70         int ans=0;
    71         for(int j=0; j<=n; j++)
    72             for(int i=1; i<=m; i++)
    73                 ans=max(d[n][i],ans);
    74 
    75         printf("%d
    ",ans);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    修改ecshop的100种技巧
    解决ecshop后台生成菜单出现乱码的问题
    记录搜索历史ecshop
    ecshop 收货人信息电话必填改为手机必填
    ecshop 后台goods表添加字段
    想想而已。。。
    微信网页第三方登录原理
    Linux kprobe初探
    bcc-tools工具之profile
    归并排序c语言
  • 原文地址:https://www.cnblogs.com/assult/p/3959755.html
Copyright © 2011-2022 走看看