本题链接(单击这里)
题意:
给一个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; }