1. One-dimensional array for maximum sub-segments and; (hdu1003,hoj1760)
This is the most basic of the largest sub-segments and models: given a sequence a[0],a[1],a[2],... a[n], requiring a continuous paragraph, so that the sum of the largest. If you set Dp[i] to represent the largest sum ending with the first element, then there are obviously:
Dp[i] = Dp[i-1] + a[i] (Dp[i-1] > 0 o'clock)
A[i] (Dp[i-1] < 0 o'clock)
Obviously, the spatial complexity of this model can be compressed to O (1), i.e.:
DP + = A[i] (dp > 0)
DP = A[i] (DP < 0)
http://acm.hdu.edu.cn/showproblem.php?pid=1003
AC (contains maximum and starting position and end position)
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <iomanip>
#include <numeric>
#include <istream>//Basic input stream
#include <ostream>//Basic output stream
#include <sstream>//string-based streaming
#include <utility>//stl Generic template class
#include <complex.h>//complex processing
#include <fenv.h>//floating-point environment
#include <inttypes.h>//integer format conversion
#include <stdbool.h>//Boolean environment
#include <stdint.h>//Integral environment
#include <tgmath.h>//general type Math macro
#define L (A,B,C) for (int a = B;a >= c;a-)
#define M (A,B,C) for (int a = B;a <= C;a + +)
#define N (A, B) memset (A,b,sizeof (a));
const INT max=1<<30;
const int Min=-max;
using namespace Std;
int dp[100011],a[100011];
int main ()
{
int num=0,t,n;
cin>>t;
while (t--)
{
N (dp,0);
cin>>n;
for (int i=1; i<=n; i++)
cin>>a[i];
DP[1]=A[1];
int ans=a[1]; Sum
int end=1,begin=1,start=1;
M (I,2,n)
{
if (A[i]<=dp[i-1]+a[i])
Dp[i]=dp[i-1]+a[i];
else//start record at this time enter the first position that satisfies test instructions
Dp[i] = a[i],start=i;
if (Ans<dp[i])
ans = dp[i],end=i,begin=start; Record End Position
}
cout<< "Case" <<++num<< ":" <<endl<<ans<< "" <<begin<< "<<end <<endl;
if (T)
cout<<endl;
}
return 0;
}
http://acm.hit.edu.cn/hoj/problem/view?id=1760
AC
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <iomanip>
#include <numeric>
#include <istream>//Basic input stream
#include <ostream>//Basic output stream
#include <sstream>//string-based streaming
#include <utility>//stl Generic template class
#include <complex.h>//complex processing
#include <fenv.h>//floating-point environment
#include <inttypes.h>//integer format conversion
#include <stdbool.h>//Boolean environment
#include <stdint.h>//Integral environment
#include <tgmath.h>//general type Math macro
#define L (A,B,C) for (int a = B;a >= c;a-)
#define M (A,B,C) for (int a = B;a <= C;a + +)
#define N (A, B) memset (A,b,sizeof (a));
#define MAXX (a) (a) > (b) a:b)
#define MINN (a) (a) < (b) a:b)
const INT max=1<<30;
const int Min=-max;
const int n=10010;
using namespace Std;
int dp[n],a[n];
int main ()
{
int n;
while (scanf ("%d", &n) &&n)
{
N (dp,0)
M (I,1,n)
cin>>a[i];
int max=-1;
M (I,1,n)
{
if (dp[i]>0)
Dp[i+1]=dp[i]+a[i];
Else
Dp[i+1]=a[i];
if (Dp[i+1]>max)
MAX=DP[I+1];
}
if (max>0)
printf ("The maximum winning streak is%d.\n", Max);
Else
printf ("Losing streak.\n");
}
return 0;
}
2. Max M sub-segment and (HDU1024, POJ2479)
It is known that there are N numbers, and the sum of the Changan values of the non-intersecting m-segments is maximal.
State transition equation: Dp[i][j] Represents the number of J-segments with an I-ending element and
Dp[i][j]=max (Dp[i-1][j]+a[i],dp[i-k][j-1]+a[i]); of which (j-1<=k<=n-m+1)
This question realizes this idea:
for (i=1;i<=m;i++)
{
maxx= ( -1) * (n*90);//initialization
for (j=i;j<=n;j++)
{
Num[j]=max (Num[j-1]+a[j],pre[j-1]+a[j]);//Where now[j-1] represents the number of element I segments ending in j-1, and pre[j-1] represents the number of j-1 segments in the first I-1 element and
pre[j-1]=maxx;//is placed here to implement PRE[J-1]+A[J] a[j] is a separate sub-segment, then you should use the I-1 segment
if (Num[j]>maxx)
{
MAXX=NUM[J];
}
}
}
http://acm.hdu.edu.cn/showproblem.php?pid=1024
AC
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <iomanip>
#include <numeric>
#include <istream>//Basic input stream
#include <ostream>//Basic output stream
#include <sstream>//string-based streaming
#include <utility>//stl Generic template class
#include <complex.h>//complex processing
#include <fenv.h>//floating-point environment
#include <inttypes.h>//integer format conversion
#include <stdbool.h>//Boolean environment
#include <stdint.h>//Integral environment
#include <tgmath.h>//general type Math macro
#define L (A,B,C) for (int a = B;a >= c;a-)
#define M (A,B,C) for (int a = B;a <= C;a + +)
#define N (A, B) memset (A,b,sizeof (a));
#define MAXX (a) (a) > (b) a:b)
#define MINN (a) (a) < (b) a:b)
const INT max=1<<30;
const int Min=-max;
const int n=1001000;
using namespace Std;
int a[n],pre[n],num[n];
int main ()
{
int n,m;
while (Cin>>m>>n)
{
for (int i=1;i<=n;i++)
cin>>a[i];
N (num,0);
N (pre,0);
int Maxx;
M (I,1,M)
{
Maxx=min;
M (J,i,n)
{
Num[j]=max (Num[j-1]+a[j],pre[j-1]+a[j]);
Pre[j-1]=maxx;
if (Num[j]>maxx)
MAXX=NUM[J];
}
}
cout<<maxx<<endl;
}
return 0;
}
http://poj.org/problem?id=2479
AC
(timed out with C + + input)
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#define L (A,B,C) for (int a = B;a >= c;a-)
#define M (A,B,C) for (int a = B;a <= C;a + +)
#define N (A, B) memset (A,b,sizeof (a));
#define MAXX (a) (a) > (b) a:b)
#define MINN (a) (a) < (b) a:b)
const INT max=1<<30;
const int Min=-max;
const int n=50005;
using namespace Std;
int a[n],pre[n],num[n];
int main ()
{
int n,t;
scanf ("%d", &t);
while (t--)
{
scanf ("%d", &n);
for (int i=1; i<=n; i++)
scanf ("%d", &a[i]);
N (num,0);
N (pre,0);
int Maxx;
M (i,1,2)
{
Maxx=min;
M (J,i,n)
{
Num[j]=max (Num[j-1]+a[j],pre[j-1]+a[j]);
Pre[j-1]=maxx;
if (Num[j]>maxx)
MAXX=NUM[J];
}
}
cout<<maxx<<endl;
}
return 0;
}
3. Maximum sub-matrices and
The so-called original aim, this idea is the same as above. Dimension is added one dimension, so consider turning it into a one-dimensional "basic problem". We can first Count Sum[i][j] (the following assumes the subscript starts from 1): line I, the total value from the beginning to the J element, so that line I from the J element to the K element is the sum of sum[i][k]-sum[i][j-1]. The time complexity of this preprocessing is O (n^2). At this point, the problem is transformed into one-dimensional maximum sub-segments and problems: enumerating each line, the first and the first J elements (1 <= i <= j <= N), you can think of the sum of the J-i + 1 elements as an element (the process of conversion), and then the N such elements to find the largest sub-paragraph and can. The time complexity of this part is O (n^3), so the total complexity is also O (n^3).
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1074
AC
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <iomanip>
#include <numeric>
#include <istream>//Basic input stream
#include <ostream>//Basic output stream
#include <sstream>//string-based streaming
#include <utility>//stl Generic template class
#include <complex.h>//complex processing
#include <fenv.h>//floating-point environment
#include <inttypes.h>//integer format conversion
#include <stdbool.h>//Boolean environment
#include <stdint.h>//Integral environment
#include <tgmath.h>//general type Math macro
#define L (A,B,C) for (int a = B;a >= c;a-)
#define M (A,B,C) for (int a = B;a <= C;a + +)
#define N (A, B) memset (A,b,sizeof (a));
#define MAXX (a) (a) > (b) a:b)
#define MINN (a) (a) < (b) a:b)
const INT max=1<<30;
const int Min=-max;
using namespace Std;
int dp[111][111],a[111][111];
int main ()
{
int n;
while (Cin>>n)
{
N (dp,0)
M (i,1,n)//input matrix value of the corresponding position
M (J,1,n)
cin>>a[i][j];
M (I,1,n)
{
int t=0;
M (J,1,n)//Add and count the elements of each row into the DP array
{
T+=A[I][J];
dp[i][j]=t;
}
}
int ans,max=min;
M (i,1,n)//Start position of each row
{
M (j,i,n)//location to which each line can reach
{
ans=0; Record values for each step
M (K,1,n)//k for number of rows
{
int t=dp[k][j]-dp[k][i-1];
if (ans>0)
ans+=t;
Else
ans=t;
if (Ans>max)//Find the maximum value
Max=ans;
}
}
}
cout<<max<<endl; Maximum output value
}
return 0;
}
4. Maximum sub-cubes