• C


    用二位数组dp[i][j]记录组数为i,前j个数字的最大子段和。

    转移方程dp[i][j]=min(dp[i][j-1],dp[i-1][k])+arr[j],方程表示的是考虑到第j个数,可以把它直接加入到第i组,也可以作为第i组的开头,如果作为第i组的开头,就要考虑第i-1组该以哪个数结尾。直接枚举k,k从(i-1)到j-1。

    优化:因为题目n值范围过大,显然二维数组不行。而d[i][x]只与d[i-1][x]有关,所以可以将其降低至一维。即dp[j]表示前j个数所分段后的和。因为dp[i-1][k]的取值需要一重循环,极有可能导致超时,所以使用数组max[],存储当前层的最大值,以供下一层求值使用。dp[j] = max(dp[j-1] + a[j], max[j-1] + a[j]) 

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+7;
    const int INF=1e9+7;
    int dp[N];
    int arr[N];
    int ma[N];
    int main(){
        int n,m;
        while(cin>>m>>n){
            memset(ma,0,sizeof ma);
            for(int i=1;i<=n;i++) 
                scanf("%d",&arr[i]);
            int tmp;
            for(int i=1;i<=m;i++){//第i组
                tmp=-INF;
                for(int j=i;j<=n;j++){//考虑第j个人
                    dp[j]=max(dp[j-1],ma[j-1])+arr[j];
                    ma[j-1]=tmp;//此时tmp的值还没有更新,所以应该是当j=j-1时的最大值 
                    tmp=max(tmp,dp[j]);
                }
            }
            printf("%d
    ",tmp);
        }
        return 0;
    } 
  • 相关阅读:
    Java 对象初始化
    Java 栈和堆
    值得细品
    磁盘的分区、格式化与挂载
    VirtualBox预存空间不足
    做个备忘
    SQL查数据库有哪些触发器,存储过程...
    SQL 中 CASE
    FMX的Style中的Effects的注意问题
    Python图像处理库(2)
  • 原文地址:https://www.cnblogs.com/Accepting/p/12408592.html
Copyright © 2020-2023  润新知