I flashed the idea of a monotone queue optimization, and I thought about burning it all over the left and right sides. but not sure, searched the puzzle, found that it is really a monotonous queue, and then wrote for a long time, the adjustment of the subscript should be how to change before.
DP[I][J] Indicates the maximum value of the first line of the J Bar.
DP[I][J] = max (dp[i-1][k]+pre[i][j-1]-pre[i][k-1]); From left to right
DP[I][J] = max (dp[i][j],dp[i-1][k]+suf[i][j]-suf[i][k]); From right to left
1 #pragmaWarning (disable:4996)2 #pragmaComment (linker, "/stack:1024000000,1024000000")3#include <stdio.h>4#include <string.h>5#include <time.h>6#include <math.h>7#include <map>8#include <Set>9#include <queue>Ten#include <stack> One#include <vector> A#include <bitset> -#include <algorithm> -#include <iostream> the#include <string> -#include <functional> - Const intINF =1<< -; - typedef __int64 LL; + /* - Dp[i][j] means to go to the first line, the maximum value of the J vertical Bar + Dp[i][j] = max (Dp[i-1][k] + sum[j-1]-sum[k-1]) A monotonic Queue Optimization Maintenance team first maximum value, at */ - - intq[11111], head, tail; - intdp[111][11111]; - inta[111][11111]; - intb[111][11111]; in intpre[111][11111], suf[111][11111]; - intsum1[111][11111]; to intsum2[111][11111]; + intMain () - { the intN, M, K; * $ while(SCANF ("%d%d%d", &n, &m, &k), n+m+k)Panax Notoginseng { -Memset (DP,0,sizeof(DP)); thememset (PRE,0,sizeof(pre)); +memset (Suf,0,sizeof(Suf)); Amemset (SUM1,0,sizeof(SUM1)); thememset (sum2,0,sizeof(sum2)); +n++; - for(inti =1; I <= n;++i) $ { $ for(intj =1; J <= m;++j) - { -scanf"%d", &a[i][j]); thePRE[I][J] = pre[i][j-1] +A[i][j]; -SUF[I][J] =A[i][j];Wuyi } the for(intj = M;j >=1;--j) -SUF[I][J] + = Suf[i][j +1]; Wu - } About for(inti =1; I <= n;++i) $ { - for(intj =1; J <= m;++j) - { -scanf"%d", &b[i][j]); ASUM1[I][J] =B[i][j]; +SUM2[I][J] = sum2[i][j-1] +B[i][j]; the } - for(intj = M;j >=1;--j) $SUM1[I][J] + = Sum1[i][j +1]; the } the for(inti = N;i >=1;--i) the { theHead = Tail =0; - for(intj =1; J <= m +1;++j) in { the while(Head < tail && Dp[i +1][J]-Pre[i][j-1] >= Dp[i +1][q[tail-1]]-Pre[i][q[tail-1] -1]) thetail--; Aboutq[tail++] =J; the while(Head<tail && sum2[i][j-1]-sum2[i][q[head]-1]>k) thehead++; theDP[I][J] = dp[i +1][q[head]] + pre[i][j-1]-pre[i][q[head]-1]; + } -Head = Tail =0; the Bayi for(intj = m+1; J >=1;--j) the { the while(Head < Tail&&dp[i +1][J]-suf[i][j] >= dp[i +1][q[tail-1]]-Suf[i][q[tail-1] ]) -tail--; -q[tail++] =J; the while(Head<tail&&sum1[i][j]-sum1[i][q[head]]>k) thehead++; theDP[I][J] =std::max (Dp[i][j], dp[i +1][q[head]] + suf[i][j]-Suf[i][q[head]]); the } - } the intAns =0; the for(intj =1; J <= m +1;++j) theAns = std::max (ans, dp[1][j]);94printf"%d\n", ans); the } the return 0; the}View Code
uvalive4327 (monotonic queue optimization)