首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

HDU 4374 One hundred layer(单一队列+DP)

2012-09-06 
HDU 4374 One hundred layer(单调队列+DP)#include iostream#include cstring#include cstdio#inclu

HDU 4374 One hundred layer(单调队列+DP)


#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>using namespace std;const int maxn = 111;const int maxm = 10010;const int oo = 1 << 30;int n, m, x, t;int s[maxn][maxm];int sum[maxn][maxm]; int dp[maxn][maxm];int head, tail;int myque[maxm][2];int SUM(int i, int j, int k){    if (j > k) {        return 0;    }    return sum[i][k] - sum[i][j-1];}int main(){    while (scanf("%d%d%d%d", &n, &m, &x, &t) != EOF) {        for (int i = 1; i <= n; ++i) {            sum[i][0] = 0;            for (int j = 1; j <= m; ++j) {                scanf("%d", &s[i][j]);                sum[i][j] = sum[i][j-1] + s[i][j];                dp[i][j] = -oo;            }        }        for (int i = x; i >= x - t && i >= 1; --i) {            dp[1][i] = sum[1][x] - sum[1][i-1];        }        for (int i = x; i <= x + t && i <= m; ++i) {            dp[1][i] = sum[1][i] - sum[1][x-1];        }        for (int i = 2; i <= n; ++i) {            // 从上一层的左边到达本层             head = tail = 0;            for (int j = 1; j <= m; ++j) {                while (head != tail && myque[tail-1][1] <= dp[i-1][j] - SUM(i, 1, j - 1)) {                    tail--;                }                myque[tail][0] = j;                myque[tail][1] = dp[i-1][j] - SUM(i, 1, j - 1);                tail++;                while (j - myque[head][0] > t) {                    head++;                }                dp[i][j] = max(dp[i][j], myque[head][1] + SUM(i, 1, j));            }            // 从上一层的右边到达本层             head = tail = 0;            for (int j = m; j >= 1; --j) {                while (head != tail && myque[tail-1][1] <= dp[i-1][j] + SUM(i, 1, j)) {                    tail--;                }                myque[tail][0] = j;                myque[tail][1] = dp[i-1][j] + SUM(i, 1, j);                tail++;                while (myque[head][0] - j > t) {                    head++;                }                dp[i][j] = max(dp[i][j], myque[head][1] - SUM(i, 1, j - 1));            }        }        int ans = -oo;        for (int i = 1; i <= m; ++i) {            ans = max(ans, dp[n][i]);        }        printf("%d\n", ans);    }    return 0;}


热点排行