這是一道DP經典題(感受什麼都經典)也是很常見的一個題型,具體思路就是用sum記錄一個前綴和,從a[1]遍歷到a[n]每次,加上去,可是一旦sum成了負數,就不必前綴和了,從新賦值0(由於前面就是累贅了)而後,就作出來了........php
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,maxx,sum; 4 int main() 5 { 6 scanf("%d%d",&n,&sum); 7 maxx=sum; 8 //先記錄第一個值,由於全部都是負數時,maxx就會是0,因此要不預先處理,要不賦值負無窮 9 while(--n) 10 { 11 scanf("%d",&x); 12 sum=max(sum,0);//看負數就不要了 13 sum+=x;//加上去 14 maxx=max(maxx,sum);//曲最大子段和 15 } 16 printf("%d",maxx); 17 }
學完了最大子段和後,該學最大子陣和了(欸嘿嘿)。對於求二維的這玩意兒,咱們壓成一位就能夠了。確定會有人問,怎麼壓成一維?c++
康康這個樣例,咱們枚舉要選取的矩陣的寬度spa
(不要問我爲何是豎着的,由於方便一些)code
而後咱們就把這兩豎行壓成一豎行blog
我知道豎着難受,可是....我懶得改了ci
而後咱們用正規的最大子段和求就好了啦get
至於這個壓行的操做,咱們記錄一個前綴和,枚舉區間左右邊界便可it
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,ans; 4 int mp[105][105]; 5 int qzh[105][105]; 6 int main() 7 { 8 while(cin>>n) 9 { 10 ans=-1e9;//必定要負無窮,避免後邊負數,ans爲0 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=n;j++) 13 scanf("%d",&mp[i][j]);//輸入 14 for(int i=1;i<=n;i++) 15 for(int j=1;j<=n;j++) 16 qzh[i][j]=qzh[i][j-1]+mp[i][j];//前綴和(變量名生動形象) 17 for(int i=1;i<=n;i++)//枚舉區間右下標 18 { 19 for(int j=0;j<i;j++)//枚舉區間 左下標 20 { 21 int sum,maxx;//剩下就是最大子段和啦 22 sum=maxx=qzh[1][i]-qzh[1][j]; 23 for(int l=2;l<=n;l++) 24 { 25 int x=qzh[l][i]-qzh[l][j]; 26 sum=max(sum,0); 27 sum+=x; 28 maxx=max(maxx,sum); 29 } 30 ans=max(ans,maxx); 31 } 32 } 33 cout<<ans<<endl; 34 } 35 }