zoukankan      html  css  js  c++  java
  • hdu 1024 Max Sum Plus Plus

    主要参考这篇文章

    http://hi.baidu.com/eizi/blog/item/3c12270987a4ad38e9248880.html


    题意:

    给你n个数的序列,从中取m段不相交的序列[ai,bi](1<=i<=m)使得这m段的和是所有可能中和最大的.


    思路:

    用dp[i][j]表示第i段以j结尾的最大值,两种情况:(1).将j连到以j-1为结尾的第i段后面;(2).a[j]单独作为第i段,那么第i-1段可能以i-1.....j-1 结尾.

    状态转移方程: dp[i][j]=max{dp[i][j-1]+a[j] , dp[i-1][k]+a[j](i-1<=k<j) };

    for(i=1;i<=m;i++)

    for(j=1;j<=n;j++)

    {

    dp[i][j]=dp[i][j-1]+a[j];

    for(k=i-1;k<j;k++)

    dp[i][j]=max{ dp[i][j] , dp[i-1][k]+a[j] };

    }

    数据范围是1000,000三重循环无疑超时,分析容易知道第i段只和第i-1段的状态有关,

    用 f[i] 表示当前处理的 i 段

    用 pre[i-1] 表示当前处理之前的 i -1 段

    所以 f[i] = max ( f[i-1] , pre[i-1] ) + a[j] ;

    #include"stdio.h"
    #define MAX 1000005
    int a[MAX],f[MAX],pre[MAX];
    int n,m,maxx;
    int max(int x,int y)
    {
    	return x<y?y:x;
    }
    int main()
    {
    	int i,j;
    	while(scanf("%d%d",&m,&n)!=-1)
    	{
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&a[i]);
    			pre[i]=f[i]=0;
    		}
    		f[0]=pre[0]=0;
    		for(i=1;i<=m;i++)
    		{
    			maxx=-999999999;
    			for(j=i;j<=n;j++)
    			{
    				f[j]=max(f[j-1],pre[j-1])+a[j];
    				pre[j-1]=maxx;
    				maxx=max(maxx,f[j]);
    			}
    		}
    		printf("%d\n",maxx);
    	}
    	return 0;
    }




  • 相关阅读:
    HTML 笔记
    JavaScript 学习笔记
    对近期的一些总结
    【 Java 】手速手速~
    【 Java 】 简易交通灯
    【 Art 】小心心~
    scala 标识符案例
    scala 基础类型
    scala 类、字段、方法
    scala 列表
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365352.html
Copyright © 2011-2022 走看看