本题链接(单击这里)
题意:
给一个n*n的距阵,要求求出最的子距阵和。
思路:
这道题的关键就是怎么找到所有的子距阵,
然后用表解示。。。。
下面是案例
这是一个数组a
0 | -2 | -7 | 0 |
9 | 2 | -6 | 2 |
-4 | 1 | -4 | 1 |
-1 | 8 | 0 | -2 |
0 | -2 | -7 | 0 |
这是第一行的最大子距阵和0(第一行第一列)
9 | 0 | -13 | 2 |
这是第一行和第二行相加得到的值,最大子距阵和为9(a11+a12+a21+a22)
5 | 1 | -17 | 3 |
4 | 9 | -17 | 1 |
这样就找完以第一行为初始行的子距阵。
然后再找以第二行为初始行的子距阵。
b数组的初始值为第二行
9 | 2 | -6 | 2 |
再往下找就能找到
4 | 11 | -12 | 5 |
========================
按照上面的方法一直找下去就行了,这题用文字描述感觉有点困难。。。。。。。。。
上代码吧
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int a[110][110];
int dp[110][110];
int Max;
void funt(int s[],int n)
{
int sum[110];
sum[1]=s[1];
for(int i=2;i<=n;i++)
{
if(sum[i-1]<=0)
sum[i]=s[i];
else
sum[i]=sum[i-1]+s[i];
if(Max<sum[i])
Max=sum[i];
}
}
int main()
{
int N;
scanf("%d",&N);
Max=-1000000;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=N;i++)
{
int s[110];
memset(s,0,sizeof(s));
for(int j=i;j<=N;j++)
{
for(int k=1;k<=N;k++)
s[k]+=a[j][k];
funt(s,N);
}
}
printf("%d\n",Max);
return 0;
}