做題的時候遇到了乙個最大矩陣和,搜了一下是從最大子串行和演變而來的,所以先做一下最大子串行和。
這個有乙個需要注意的事情是,如果矩陣裡面所有的元素都是負值,可以返回0,也可以返回最大負數,看具體題目要求
對陣列來說,乙個最大的子串行可以通過遍歷從每乙個位置開始的序列中得到,所以我們遍歷如a1,a2,…,an; a2,a3,…,an等不同長度不同起始位置的序列,不過時間複雜度太高o(n^3),優化一下(儲存加和)也不過是o(n^2)。
在這裡,分治法的思想主要體現在,首先將原始序列分成左右兩個部分,然後將最終的最大子串行的情況分成了三種。
最大的子串行完全在原始序列左側。
最大的子串行完全在原始序列右側。
最大的子串行橫跨左右兩側。
其中可能讓你迷惑的是第三個情況,如果橫跨的話,那不就又相當於最原始的,不劃分左右的情況嗎?其實不是,我們在找左右最大兩個子串行的時候,左側是從middle遍歷到left,右側是從middle+1遍歷到right,也就是說,我們得到的左右最大的子串行是連續的,橫跨左右兩側的情況,也只是乙個合併的過程,就是left_max+right_max。
#include
using
namespace
std;
//求三個元素的最大值
int max_of_three(int i, int j, int k)
return max_of_three(j, k, i);
}int maxsequence(int a, int left, int right)
}//再找右側的最大元素
int right_max = a[middle+1], right_sum = 0;
for (int i = middle+1; i <= right; i++)
}//返回中比較的物件分別是,橫跨的,左側的,右側的最大子串行。
return max_of_three(left_max+right_max, maxsequence(a, left, middle), maxsequence(a, middle+1, right));
}
我們再來理性分析一下。
最大子串行不可能從負數開始。如果從負數開始,那麼假設a1是負數,a1+a2+a3
int maxsequence1(int a, int n)
if (sum > maxsum)
}return maxsum;
}
引用自這一篇文章
我實在是不會動態規劃……我明天就去學動態規劃嗚嗚嗚
#include
#include
using
namespace
std;
#define inf 0x3f3f3f3f;
int n,m;
int a[505][505],b[505],dp[505];
int res=-inf;
int main()
} }
cout
0;
}
最大子段和 最大子矩陣和
給出n個整數序列 可能為負數 組成的序列a1,a2,an,求該序列形如 的子段和的最大值。當所有整數均為負數時,定義最大子段和為0。多測試用例。每個測試用例佔2行 第一行是序列的個數n 0 n 10000 第二行是n個整數。為每個測試用例輸出一行結果 最大子段和。6 2 11 4 13 5 2 31...
最大子矩陣和
前言 今天花了很長時間,看了無數人寫的帖子,但是幾乎沒有人把這個問題一下子說得很清楚,所以,我把這個問題按照自己的思路寫出來,希望能夠把這個問題講清楚。問題 求乙個m n的矩陣的最大子矩陣和。比如在如下這個矩陣中 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 擁有最大和的子矩陣為 ...
最大子矩陣和
前言 今天花了很長時間,看了無數人寫的帖子,但是幾乎沒有人把這個問題一下子說得很清楚,所以,我把這個問題按照自己的思路寫出來,希望能夠把這個問題講清楚。問題 求乙個m n的矩陣的最大子矩陣和。比如在如下這個矩陣中 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 擁有最大和的子矩陣為 ...