acm-poj1050解題報告
題目地址:http://poj.org/problem?id=1050
題目大意:簡單易懂,求一個最大為100*100矩陣中的子矩陣中元素之和的最大值
解題思路:說實話這道題算是DP,本人現在正在補,對DP還是不太熟悉,甚至還在網上參考了一些演算法過程以及思路才寫出的程式碼,最後終於AC了(笑)
首先,解這道題要有求最大子段和的基礎,如給你一個數組a,求陣列中a[i]+a[i+1]+...+a[j]的最大值
解法很簡單,參考如下:
int b=0,sum=-100000000;
for(int i=0;i<n;i++)
{
if(b>0) b=b+a[i];
else b=a[i];
if(b>sum) sum=b;
}
再說本道題,主要思想為將其轉化為一維陣列求最大子段和,如果最優解左起第i列,右止於第j列,那麼我們相當於把這些列的對應位加和,成為一列,
並對改列求最大子段和即可(降維思想)。
程式碼:
#include<cstdio>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
#define maxn 105
#define inf 0x3f3f3f3f
int array[maxn][maxn];
int f[maxn][maxn][maxn];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++){scanf("%d", &array[i][j]);}
}
memset(f, 0, sizeof(f));
int ans=-inf;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int sum=0;
for(int k=j;k<=n;k++)
{
sum+=array[i][k];
f[i][j][k]=max(f[i-1][j][k]+sum,sum);//i是指行,j是起始列,k是終結列,f存的值為在ijk範圍內的元素和最大值
ans=max(ans,f[i][j][k]);
}
}
}
cout<<ans<<endl;
return 0;
}