• 数组分组(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
    ",dp[n]);
    45     return 0;
    46 }

    -

  • 相关阅读:
    wenbao与分治
    wenbao与贪心
    wenbao与高精度
    wenbao与FFT
    wenbao与卡特兰数
    wenbao与类
    wenbao与取整函数
    wenbao与字符串转化
    wenbao与scanf
    wenbao与数字与字符串
  • 原文地址:https://www.cnblogs.com/jiamian/p/12200890.html
Copyright © 2020-2023  润新知