线性DP,使用单调队列优化。
1 /* 4374 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 const int INF = 0x3f3f3f3f; 44 const int maxn = 105; 45 const int maxm = 10005; 46 int n, m, x, t; 47 int score[maxn][maxm]; 48 int dp[maxn][maxm]; 49 int P[maxm], Q[maxm]; 50 int sum[maxm]; 51 52 void solve() { 53 int i, j, k; 54 int lpos, rpos; 55 int l, r, tmp; 56 57 for (i=1; i<=n; ++i) 58 for (j=1; j<=m; ++j) 59 dp[i][j] = -INF; 60 61 for (j=1; j<=m; ++j) 62 sum[j] = sum[j-1] + score[1][j]; 63 for (lpos=max(1,x-t),j=lpos; j<=x; ++j) 64 dp[1][j] = sum[x] - sum[j-1]; 65 for (rpos=min(m,x+t),j=rpos; j>x; --j) 66 dp[1][j] = sum[j] - sum[x-1]; 67 68 for (i=2; i<=n; ++i) { 69 for (j=1; j<=m; ++j) 70 sum[j] = sum[j-1] + score[i][j]; 71 72 // k <= j 73 l = 1, r =0; 74 for (j=1; j<=m; ++j) { 75 lpos = max(1, j-t); 76 tmp = dp[i-1][j] - sum[j-1]; 77 while (l<=r && Q[r]<=tmp) 78 --r; 79 Q[++r] = tmp; 80 P[r] = j; 81 while (P[l] < lpos) 82 ++l; 83 dp[i][j] = max(dp[i][j], Q[l] + sum[j]); 84 } 85 86 // k>=j 87 l = 1, r =0; 88 for (j=m; j>=1; --j) { 89 rpos = min(m, j+t); 90 tmp = dp[i-1][j] + sum[j]; 91 while (l<=r && Q[r]<=tmp) 92 --r; 93 Q[++r] = tmp; 94 P[r] = j; 95 while (P[l] > rpos) 96 ++l; 97 dp[i][j] = max(dp[i][j], Q[l] - sum[j-1]); 98 } 99 } 100 101 int ans = -INF; 102 103 rep(j, 1, m+1) 104 ans = max(ans, dp[n][j]); 105 106 printf("%d\n", ans); 107 } 108 109 int main() { 110 ios::sync_with_stdio(false); 111 #ifndef ONLINE_JUDGE 112 freopen("data.in", "r", stdin); 113 freopen("data.out", "w", stdout); 114 #endif 115 116 while (scanf("%d %d %d %d", &n, &m, &x, &t)!=EOF) { 117 rep(i, 1, n+1) 118 rep(j, 1, m+1) 119 scanf("%d", &score[i][j]); 120 solve(); 121 } 122 123 #ifndef ONLINE_JUDGE 124 printf("time = %d.\n", (int)clock()); 125 #endif 126 127 return 0; 128 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**5 11 # fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = randint(1, 100) 14 m = randint(1, 10000) 15 x = randint(1, m) 16 t = randint(1, m) 17 fout.write("%d %d %d %d\n" % (n, m, x, t)) 18 for i in xrange(n): 19 L = [] 20 for j in xrange(m): 21 x = randint(-500, 500) 22 L.append(x) 23 fout.write(" ".join(map(str, L)) + "\n") 24 25 26 def MovDataIn(): 27 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 28 shutil.copyfile("data.in", desFileName) 29 30 31 if __name__ == "__main__": 32 GenDataIn() 33 MovDataIn()
时间: 2024-10-04 02:19:57