Original title: http://acm.hdu.edu.cn/showproblem.php?pid=1081
Main topic:
For a square of a given edge length, select a rectangle so that it contains the largest value of all the elements.
As we all know (a+b) ^2, the optimization here is using this principle to do optimization, our DP value is the value of the rectangular area of our former I row J column.
The values of any rectangular area can also be solved by this expansion, so we can violently enumerate each of the cases in the upper-left corner (k,l) to the lower-right corner (I,J).
For this side length is 100, the 4-layer loop is 10^8, because the loop and not run so much, just can also card past.
The code is as follows:
#include <iostream>#include "Cstdio"#include "string.h"using namespace STD;Const intN = the;intA[n][n];intDp[n][n];intAns[n][n];intN,m;intMain () {//freopen ("In.txt", "R", stdin); while(scanf("%d", &n)!=eof) {//Initialize memsetA0,sizeof(a));memset(DP,0,sizeof(DP));memset(ANS,0,sizeof(ans)); for(intI=0; i<=n; i++) for(intj=0; j<=n; J + +) ans[i][j]=-12345678;//Read graph for(intI=1; i<=n; i++) for(intj=1; j<=n; J + +)scanf("%d", &a[i][j]);//Optimization for(intI=1; i<=n; i++) for(intj=1; j<=n; J + +) dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+A[I][J];//Brute Force enumeration for(intI=n; i>=1; i--) for(intJ=n; j>=1; j--) for(intk=1; k<=i; k++) for(intL=1; l<=j; l++) Ans[i][j]=max (Ans[i][j],dp[i][j]-dp[i-k][j]-dp[i][j-l]+dp[i-k][j-l]);//Find maximum value intan=-12345678; for(intI=1; i<=n; i++) for(intj=1; j<=n; J + +) An=max (An,ans[i][j]);printf("%d\n", an); }//fclose (stdin); return 0;}
Above we are enumerating fixed (I,J) moves (k,l), because as soon as we run through all the points, the change in the position relationship of the 4 loops does not affect the result, so we can change the four-layer for loop to this:
for(intI=n;I>=1;I--) for(int k=1; k<=I; k++) for(intJ=n;J>=1;J--) for(int l=1; l<=J; l++)ans[i][j]=max (ans[i][j]Dp[i][j]-dp[I-k][j]-dp[i][J-l]+dp[I-k][J-l]);
Here we first fix the upper and lower bounds of the rectangular region, and then enumerate the left and right boundaries. This should be well understood, so how can we optimize the rest?
When we k=i+1, we ask for the largest contiguous rectangle of a single row and can be considered as the maximum continuity of a one-dimensional array, and we only need the time complexity of O (n) to sweep past.
When we want to calculate the k=i+2, we just need to add the value of this one array to the corresponding number of columns, and then O (n) to find these results.
Since K and I are enumerating n^2, the time complexity of this optimization is O (n^3).
#include <iostream>#include "Cstdio"#include "string.h"#include "vector"using namespace STD;Const intN = the;Const intINF =1<< in;intA[n][n];intDp[n];intSum[n];intN,m;intMain () {//freopen ("In.txt", "R", stdin); while(scanf("%d", &n)!=eof) {memsetA0,sizeof(a)); for(intI=1; i<=n; i++) for(intj=1; j<=n; J + +)scanf("%d", &a[i][j]);intAns=-inf; for(intI=1; i<=n; i++) {Reset the sum array to 0 each time you change the upper bounds memset(Sum,0,sizeof(sum)); for(intJ=i; j<=n; J + +) {//Lower bounds add the newly added number to the sum array every time + 1 o'clock for(intk=1; k<=n;k++) sum[k]=sum[k]+a[j][k];//DP solves the maximum continuous and, at any time, updates ans for(intk=1; k<=n;k++) {Dp[k]=max (sum[k],dp[k-1]+sum[k]); Ans=max (Ans,dp[k]); } } }printf("%d\n", ans); }return 0;}
The first type of time and space is: 62MS 1696K
The second type of time and space is: 15MS 1612K
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 1081 to the Max brute Force analog O (n^4) DP optimization O (n^3)