1. 程式人生 > >杭電ACM1081——To The Max

杭電ACM1081——To The Max

  開始看到這題的時候,一點頭緒都沒有,本來想用暴力解決的,可是看到n可以到100,估計了下會超時,就放棄了,想過用動歸做,但是沒有想到如何去做。就暫且放下了。

  今天再看到這題,百度了下,明白瞭如何去做了,就是將各行合併,再當作最大子序列來做,就很簡單了。

  n行,分別跟其他的行進行合併,然後動歸計算最大值,不斷的跟新最大值。

附上AC程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int dp[105], temp[105];
int num[105][105];

int main()
{
	int n, i, j;
	while(cin >> n)
	{
		for(i = 0; i < n; i++)
		{
			for(j = 0; j < n; j++)
			{
				scanf("%d", &num[i][j]);
			}
		}
		int max = -10000000;
		for(i = 0; i < n; i++)                        // 從0到n-1,分別跟其他行合併來計算,包括自己這一行
		{
			for(j = i; j < n; j++)
			{
				memset(temp, 0, sizeof(temp));       //陣列初始化為0
				if(i == j)
				{
					for(int k = 0; k < n; k++)        //屬於同一行。
						temp[k] = num[i][k];
				}
				else
				{
					for(int k = 0; k < n; k++)        //不屬於同一行,將i行到j行的值累加起來
					{
						for(int l = i; l <= j; l++)
							temp[k] += num[l][k];
					}
				}
				memset(dp, 0, sizeof(dp));            //遞推陣列初始化
				for(int k = 1; k <= n; k++)           //下面的是簡單的動歸,很簡單的
				{
					if(dp[k - 1] > 0)
						dp[k] = dp[k - 1] + temp[k - 1];
					else
						dp[k] = temp[k - 1];
					if(dp[k] > max)                    //跟新最大值
						max = dp[k];
				}
			}
		}
		cout << max << endl;
	}
	return 0;
}