POJ-1050 To the Max 二维最大子段和
題意
給我們一個二維矩陣
讓我們在找出其中的最大子矩陣和
分析
對輸入的一個矩陣
我們考慮一維線性矩陣 上的最大子段和
對于一個數(shù)串 我們的選擇策略是
res就是最后我們得到的最大子段和的結果 a[i]是數(shù)串元素
我們這里可以把它壓縮成一維
枚舉任意兩行 然后把兩行之間的行壓縮成1行
對這一行進行一維的最大字段和求解
所以最大子矩陣和就可以將二維中的任一一維壓縮成一維 然后用一維最大字段和的
辦法求解
關于一維最大字段和問題:
/* b本可以設為數(shù)組 表示以第i個元素結尾的最大字段和是多少 也就是在b[i] = max(b[i-1]+dp[i],dp[i])中選擇最大
這里就是兩種選擇 對于一個數(shù)串 為了求出最大子段和 我們可以選擇累加 也可以選擇扔掉前面的就取當前元素作為新子段的開始元素 選擇累加前綴和 還是選擇構造新子段 分別對應兩種策略 兩者取最優(yōu)
若累加時表示能夠正向讓前綴和增大我們累加
若累加只能更小 我們選擇扔掉時表示前面的元素
何時累加會變小 有兩種情況 如果此時累加和為負數(shù)
如果新元素是個負數(shù) 負數(shù)相加只能更小 所以不如取一個更大的負數(shù)
如果新元素是個正數(shù) 那么不如就取當前元素 扔掉前面的
以上兩種可能在前面累加和是負數(shù)的情況下 都選擇max的后者為最優(yōu)情況
所以當前面累加和為負數(shù) 直接扔掉 選后面的準沒錯
由于只用到前后兩個元素所以可以節(jié)省空間用一個變量簡略表示 */
code
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int n,dp[110],a[110][110]; int Max() {int b = 0,res=-130;for(int i=1;i<=n;i++){if(b>0)b+=dp[i];// 表示能如果遇到正數(shù)還能繼續(xù)遞增else b = dp[i];//如果是負數(shù) 由于負數(shù)只能越加越小 所以那么直接讓他等于當前元素res = max(res,b);//最優(yōu)化結果}return res; } int main() {scanf("%d",&n);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);}int res=-130;for(int i=1;i<=n;i++){for(int j = i;j<=n;j++){for(int k=1;k<=n;k++)dp[k]+=a[j][k];int ma = Max();res = max(ma,res); }memset(dp,0,sizeof(dp));}printf("%d\n",res);return 0; }總結
以上是生活随笔為你收集整理的POJ-1050 To the Max 二维最大子段和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DCOS实践分享(4):如何基于DC/O
- 下一篇: php 连接芒果数据库,芒果数据库mon