zoukankan      html  css  js  c++  java
  • hdu1024 最大m子串和

    1024

    题意:给一个长度为n的序列,找出m个不相交子串的和的最大值

    思路:dp[i][j]表示取第j个数,并且前j个数分成i个区间的最大值,状态转移方程为 dp[i][j]=max(dp[i][j-1]+a[j], dp[i-1][k]+a[j])(k=i-1 i i+1 ... j-1 ),dp[i][j-1]+a[j]表示前j-1个分成i个区间并且取了a[j-1],那么在a[j]取的情况下,区间数没有增加,dp[i-1][k]表示在由i-1个区间组成的答案中加入a[j],区间数+1,这里注意一点,状态转移的时候j是从j=i开始遍历的,所以就会出现一个状态 dp[i][i-1] ,这是不可能的,要初始化为-inf,然后就是时间和空间上面的优化了,空间上面,由于每次dp状态只与上一个状态有关,所以可以用滚动数组优化,空间上对k这一维进行优化,从状态转移方程不难看出dp[i-1][k]是在找上一个状态中第二维范围为i-1到j-1的最大值,这里可以每次处理出O(1)求最大值

    AC代码: 

    #include "iostream"
    #include "iomanip"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define step(x) fixed<< setprecision(x)<<
    #define mp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define ll long long
    #define endl ("
    ")
    #define ft first
    #define sd second
    #define lrt (rt<<1)
    #define rrt (rt<<1|1)
    using namespace std;
    const ll mod=1e9+7;
    const ll INF = 1e18+1LL;
    const int inf = 1e9+1e8;
    const double PI=acos(-1.0);
    const int N=1e6+100;
    
    ///d[i][j]表示在选取第j个数字的情况下,将前j个数字分成i组的最大和
    int dp[2][N],a[N],pre[N],n,m;
    int main(){
        while(scanf("%d%d",&m,&n)==2){
            for(int i=1; i<=n; ++i){
                scanf("%d",&a[i]);
            }
            int ans=-inf; mem(pre,0), mem(dp,0);
            for(int i=1,cur=1; i<=m; ++i,cur^=1){
                for(int j=i,tmp=-inf; j<=n; ++j){
                    dp[cur][i-1]=-inf;
                    dp[cur][j]=max(dp[cur][j-1]+a[j],pre[j-1]+a[j]);
                    pre[j-1]=tmp;
                    tmp=max(tmp,dp[cur][j]);
                    if(i==m) ans=max(ans,dp[cur][j]);
                }
                /*for(int j=i,tmp=-inf; j<=n; ++j){
                    tmp=max(tmp,dp[cur][j]);
                    pre[j]=tmp;
                }*/
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    实验12——java取整、猜数和猜拳
    实验11——java线程模拟卖票
    实验10—— java读取歌词文件内容动画输出
    实验09——java基于TCP实现客户端与服务端通信
    JavaSE第十四天
    javaSE第十一天
    JavaSE第十天
    JavaSE第十天
    JavaSE第九天
    JavaSE第八天
  • 原文地址:https://www.cnblogs.com/max88888888/p/7668275.html
Copyright © 2011-2022 走看看