HDU4374 (优先队列+dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4374
dp[i][j]=max(dp[i][j],dp[i][k]-sum[i][k]+sum[i][j]); k<=j&&j-k<=T
dp[i][j]=max(dp[i][j],dp[i][k]+sum[i][k]-sum[i][j]); k>=j&&k-j<=T
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 using namespace std; 6 const int INF = -1<<27; 7 const int Ni = 110; 8 const int Mi = 10010; 9 struct qnd{ 10 int val,x; 11 qnd(){} 12 qnd(int a,int b) {val=a;x=b;} 13 bool operator < (const qnd &a) const 14 { 15 if(val<a.val) return 1; 16 if(val==a.val&&x>a.x) return 1; 17 return 0; 18 } 19 }; 20 int dp[Ni][Mi]; 21 int sum[Ni][Mi]; 22 int m; 23 inline int max(int a,int b){return a>b? a:b;} 24 int main() 25 { 26 int n,x,st,i,j,a; 27 while(~scanf("%d%d%d%d",&n,&m,&x,&st)) 28 { 29 for(i=1;i<=n;i++){ 30 for(j=1;j<=m;j++){ 31 scanf("%d",&a); 32 sum[i][j]=sum[i][j-1]+a; 33 dp[i][j]=INF; 34 } 35 } 36 37 for(j=x+1;j<=m&&j-x<=st;j++) 38 dp[1][j]=sum[1][j]-sum[1][x-1]; 39 for(j=x;j>0&&x-j<=st;j--) 40 dp[1][j]=sum[1][x]-sum[1][j-1]; 41 42 for(i=2;i<=n;i++) 43 { 44 int r=1; 45 priority_queue<qnd> ql,qr; 46 for(j=1;j<=m;j++) 47 { 48 ql.push(qnd(dp[i-1][j]-sum[i][j-1],j)); 49 if(!ql.empty()) 50 { 51 qnd nd=ql.top(); 52 while(j-nd.x>st&&!ql.empty()) 53 { 54 ql.pop();nd=ql.top(); 55 } 56 if(j-nd.x<=st) 57 dp[i][j]=max(dp[i][j],nd.val+sum[i][j]); 58 } 59 60 while(r-j<=st&&r<=m) 61 qr.push(qnd(dp[i-1][r]+sum[i][r],r)),r++; 62 if(!qr.empty()) 63 { 64 qnd nd=qr.top(); 65 while(nd.x<j&&!qr.empty()) 66 { 67 qr.pop();nd=qr.top(); 68 } 69 if(nd.x>=j) 70 dp[i][j]=max(dp[i][j],nd.val-sum[i][j-1]); 71 } 72 } 73 } 74 int ans=INF; 75 for(i=1;i<=m;i++) 76 { 77 if(ans<dp[n][i]) 78 ans=dp[n][i]; 79 } 80 printf("%d\n",ans); 81 } 82 return 0; 83 } 84 /* 85 3 4 2 1 86 7 8 1 1 87 4 5 6 20 88 1 2 3 1 89 90 3 3 2 0 91 0 0 0 92 0 -50 0 93 0 0 0 94 95 3 3 2 0 96 7 8 1 97 4 5 6 98 1 2 3 99 */