zoukankan      html  css  js  c++  java
  • HDU 4374 One hundred layer

    题意:很简单,不废话了- -

    在这道题中单调队列的作用:在线性时间内维护定长区间的最值。单调队列没学过的话去学一下这题

    转移的时候dp[i][k]->dp[i+1][j],k与j的差距不超过T,分两种情况转移,k在j的左边和右边,所以维护T长度的最值,双向扫一遍就OK了

                                                                                                      (从右边扫过来

           k                   j                                          j                  k

     <--------T------->                                          <--------T------->   

    dp[i+j][j]=max(dp[i][k]+sum[i+1][j]-sum[i][k-1])   sum[i][j]为第i行的前j项和   所以可以维护一个dp[i][k]-sum[i][k-1]的最大值,每到一个位置j,在区间长度合法的情况下用维护的最大值mx+sum[i+1] [j]来更新dp[i+1][j]

     

    从右往左再来一遍即可

    代码:


    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;

    const int N=105;
    const int M=10010;
    const int inf=0x80808080;
    typedef pair<int,int> PII;


    int n,m,x,t;
    int sum[N][M],dp[N][M];
    PII que[M];
    int st,ed;



    void maintain() {
        while(ed-st>=2 && que[ed-1].first>=que[ed-2].first) que[ed-2]=que[ed-1],ed--;
    }

    int main() {
        while(scanf("%d%d%d%d",&n,&m,&x,&t)!=EOF) {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++) scanf("%d",&sum[i][j]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++) sum[i][j]+=sum[i][j-1];
            for(int i=0;i<=n;i++)
                for(int j=1;j<=m;j++) dp[i][j]=inf;
            dp[0][x]=0;
            for(int i=1;i<=n;i++) {
                st=ed=0;
                for(int j=1;j<=m;j++) {
                    que[ed++]=PII(dp[i-1][j]-sum[i][j-1],j);
                    maintain();
                    while(ed-st>=1 && que[st].second<j-t) st++;
                    dp[i][j]=max(dp[i][j],que[st].first+sum[i][j]);
                }
                st=ed=0;
                for(int j=m;j>=1;j--) {
                    que[ed++]=PII(dp[i-1][j]+sum[i][j],j);
                    maintain();
                    while(ed-st>=1 && que[st].second>j+t) st++;
                    dp[i][j]=max(dp[i][j],que[st].first-sum[i][j-1]);
                }
            }
            int ans=dp[n][1];
            for(int i=1;i<=m;i++) ans=max(ans,dp[n][i]);
            printf("%d\n",ans);
        }
        return 0;
    }

     

  • 相关阅读:
    poj 2689 大范围内素数筛选
    poj 3270 置换
    Linux命令(实时更新)
    性能测试
    sql注入
    MySQL回表查询
    MySQL数据库高可用方案
    java反射机制
    分布式数据库
    数据库的灾备
  • 原文地址:https://www.cnblogs.com/programCaiCai/p/HDU4374.html
Copyright © 2011-2022 走看看