數組分組(DP)


 

一個長度為n的數組a,我們可以把它分成任意組,每一組是一段連續的區間。

比如數組1,2,3,4,5可以分成(1,2),(3,4,5)兩個組。每個分組都有一個權值,這個權值就是分組里面每個數的乘積對1000取模的結果。對於數組a的一個分組方案,總權值就是每個分組的權值和。

那么對於數組a,分組以后最大的權值和是多少?

輸入格式

輸入第一行一個整數n(1≤n≤1000)。

接下來一行n個整數,表示數組a,數組中每個元素都小於等於100。

輸出格式

數組最大的分組權值和。

樣例輸入

7
52 26 1 36 72 48 43

樣例輸出

1596

 

 

我們用dp[i]表示前i個數分組的最大權值,對於位置i,我們可以枚舉最后一個分組的起始位置為j,計算i,j之間的權值,然后更新dp[i]即可。

為了避免過多的計算,我們需要預處理出來每個區間的乘積對1000取模的結果。

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const int mod=1e9+7;
16 const double PI = acos(-1);
17 const double eps =1e-8;
18 #define Bug cout<<"---------------------"<<endl
19 const int maxn=1e5+10;
20 using namespace std;
21 
22 int a[1010];
23 int sum[1010][1010];//sum[i][j]表示區間i~j的乘積對1000的模 
24 int dp[1010];
25 
26 int main()
27 {
28     int n;
29     scanf("%d",&n);
30     for(int i=1;i<=n;i++)
31         scanf("%d",&a[i]);
32     for(int i=1;i<=n;i++)//預處理 
33     {
34         sum[i][i]=a[i];
35         for(int j=i+1;j<=n;j++)
36             sum[i][j]=sum[i][j-1]*a[j]%1000;
37     }
38     dp[1]=a[1];
39     for(int i=2;i<=n;i++)//求dp[i] 
40     {
41         for(int j=1;j<i;j++)//向前遍歷j,更新dp[i] 
42             dp[i]=max(dp[i],dp[j]+sum[j+1][i]);
43     }
44     printf("%d\n",dp[n]);
45     return 0;
46 }

 

 

 

 

 

-


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM