最大子段(陣)和

P1115 最大子段和

  這是一道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 }

HDU To The Max

  學完了最大子段和後,該學最大子陣和了(欸嘿嘿)。對於求二維的這玩意兒,咱們壓成一位就能夠了。確定會有人問,怎麼壓成一維?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 }
相關文章
相關標籤/搜索