HDU 1024Max Sum Plus Plus(最大m字段和)

/*
     动态转移方程:dp[i][j]=max(dp[i-1]+a[i], max(dp[t][j-1])+a[i]) (j-1<=t<i)
     表示的是前i个数j个字段和的最大值是多少!
 */
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 10000
using namespace std;

int dp[N][N], num[N];

int main()
{
   int n, m, i, j, k;
   while(scanf("%d%d", &m, &n)!=EOF)
   {
      for(i=1; i<=n; i++)
        scanf("%d", &num[i]);
      memset(dp, 0, sizeof(dp));
      for(j=1; j<=m; j++)
         for(i=j; i<=n-m+j; i++)
           if(i>j)
            {
                dp[i][j]=dp[i-1][j]+num[i];
                for(k=j-1; k<i; k++)//可以用一个Max变量一直更新 j-1 到 i-1 的 最大值
                   dp[i][j]=max(dp[i][j], dp[k][j-1]+num[i]);
            }
            else dp[i][j]=dp[i-1][j-1]+num[i];
      int sum=-1;
      for(i=m; i<=n; i++)
         if(dp[i][m]>sum)
            sum=dp[i][m];
      printf("%d\n", sum) ;
   }
   return 0;
}

/*
时间上优化一下!
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N  1000010
using namespace std;

__int64 dp[N][2], num[N];

int main()
{
   __int64 n, m, i, j, k, pos;
   while(scanf("%I64d%I64d", &m, &n)!=EOF)
   {
      for(i=1; i<=n; i++)
        {
           scanf("%I64d", &num[i]);
           dp[i][0]=dp[i][1]=0;
        }
      pos=1;
      for(j=1; j<=m; j++)
         {
            dp[j][pos]=dp[j-1][pos^1]+num[j];
            __int64 Max=dp[j-1][pos^1];
            for(i=j+1; i<=n-m+j; i++)
             {
                 Max=max(Max, dp[i-1][pos^1]);//这一块直接将 k 的 for循环去掉
                 dp[i][pos]=max(dp[i-1][pos], Max)+num[i];
              }
            pos^=1;
         }
      pos^=1;
      __int64 sum=-99999999;
      for(i=m; i<=n; i++)
         if(dp[i][pos]>sum)
            sum=dp[i][pos];
      printf("%I64d\n", sum) ;
   }
   return 0;
}
/*
  内存上优化一下,一维数组求解!
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N  1000010
using namespace std;

__int64 dp[N], num[N];

int main()
{
   __int64 n, m, i, j, k, oldN;
   __int64 maxN;//记录dp[k][j-1] (k>=j-1 && k<i) 只有num[i]自己属于第 j 段 所有情况的最大值!
   while(scanf("%I64d%I64d", &m, &n)!=EOF)
   {
      for(i=1; i<=n; i++){
           scanf("%I64d", &num[i]);
           dp[i]=0;
       }
      for(j=1; j<=m; j++)
         {
            maxN=max(dp[j-1], dp[j]);// Max = max(dp[j-1][pos^1], dp[j][pos^1])
            dp[j]=dp[j-1]+num[j];
            for(i=j+1; i<=n-m+j; i++)
             {
                 oldN=dp[i];// 记录 dp[i-1][pos^1]
         dp[i]=max(maxN, dp[i-1])+num[i]  ;// dp[j][pos] = dp[j-1][pos^1] + num[j]
         maxN=max(oldN, maxN);
             }
         }
      __int64 sum=-99999999;
      for(i=m; i<=n; ++i)
         if(dp[i]>sum)
            sum=dp[i];
      printf("%I64d\n", sum) ;
   }
   return 0;
}
时间: 2024-12-30 08:58:52

HDU 1024Max Sum Plus Plus(最大m字段和)的相关文章

Hdu 5586 Sum

Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 287    Accepted Submission(s): 177 Problem Description There is a number sequence A1,A2....An,you can select a interval [l,r] or not,all the

sql-SQL表中t表有30个字段,假设有28个字段需要做分数统计,有没优化方案能够实现

问题描述 SQL表中t表有30个字段,假设有28个字段需要做分数统计,有没优化方案能够实现 假设t表有30个字段,其中28个字段需要做分数统计,f1(5分)f2(10分)f3(8分)...F28(x分) 每个字段的分数都不规则的,有什么优化方案做统计呢? 目前我现在做的办法是写了一个存储过程 用@sum统计分数 然后逐个字段做select查询,如果不为空@sum=@sum+分数 所以这里跪求各位大大看有没有解决方案 解决方案 不是很明白你的意思! sum(f1)~sum(f28),除了用存过,还

SQL函数

函数 SQL函数 使用SQL函数,您可以在一个SELECT语句的查询当中,直接计算数据库资料的平均值.总数.最小值.最大值.总和.标准差.变异数等统计.使用Recordset对象时,也可使用这些SQL函数. SQL函数包括如下:   Avg函数:计算查询中某一特定字段资料的算术平均值. Count函数:计算符合查询条件的记录数. Min, Max函数:传回指定字段之中符合查询条件的第一条.最末条记录的资料. First, Last函数:传回指定字段之中符合查询条件的最小值.最大值. StDev函

全面接触SQL语法2

sql语法 BETWEEN...AND 运算符 决定某一人数值是否介于特定的范围之内,此运算符只可以用在SQL的语句中. expr[Not]BETWEEN value1 AND value2 expr 指定要加以计算的字段与表达式的组合. value1,value2 所指明的数值范围. 例如: 若是要从职员表格查询出所有年龄介于25-30岁的员工,可以利用下面的程序来做. SELECT 姓名,年龄 BETWEEN 25 AND 30 FROM 职员表格: LIKE 操作数 用来将一字符串与另一特

全面接触SQL语法(5)

sql语法 BETWEEN...AND 运算符 决定某一人数值是否介于特定的范围之内,此运算符只可以用在SQL的语句中. expr[Not]BETWEEN value1 AND value2 expr指定要加以计算的字段与表达式的组合. value1,value2所指明的数值范围.例如:若是要从职员表格查询出所有年龄介于25-30岁的员工,可以利用下面的程序来做.SELECT 姓名,年龄 BETWEEN 25 AND 30FROM 职员表格: LIKE 操作数 用来将一字符串与另一特定字符串样式

SQL函数详解

函数|详解 SQL函数,详细描述如下: Avg函数 Avg函数,计算查询中某一特定字段资料的算术平均值. 语法为Avg(运算式).运算式,可为字段名称.运算式.或一个函数,此函数可以是一个内部或使用者定义的,但不能为其它的SQL函数. Avg函数在计算时,不包含任何值为 Null 的资料. Count函数 Count函数,计算符合查询条件的记录条数. 语法为Count (运算式).运算式,可为字段名称.*.多个字段名称.运算式.或一个函数,此函数可以是一个内部或使用者定义的,但不能为其它的SQL

水晶报表公式使用必读

公式包含两个关键部分:组件和语法.组件是创建公式所添加的部分,而语法是组织组件所遵循的规则. 在 Crystal Reports 中有几种不同种类的公式:报表.格式化.选定.搜索.运行总计条件和警报公式.报表中的多数公式为报表公式和条件格式化公式. 一.公式组件 在 Crystal Reports 中创建公式与在任何电子数据表应用程序中创建公式类似.可以在公式中使用下列组件: 字段 示例:{客户.客户名}.{客户.去年销售额} 数字 示例:1.2.3.1416 Text 示例:"数量"

Kibana——数据图形化制作

Kibana把数据图形化,可以帮助我们更好的去分析数据,找到数据里面的结构 注意看一下,上面缩看的界面,是一个聚合的结果,他是由CPU Usage图表.System Load图表.CPU usage over time图表. System Load over time图表一起构造而成的.我把这种聚合称作一组相关性的数据看板,你可以随意的组合你的看板,如果你觉得这样做是合适的.那么,CPU Usage图表.System Load图表.CPU usage over time图表. System Lo

excel-asp.net把DataTable里的数据导出到Excel 并且要做合并 某列里多行合并的操作

问题描述 asp.net把DataTable里的数据导出到Excel 并且要做合并 某列里多行合并的操作 把DataTable里的数据导出到Excel 并且要做合并 某列里多行合并的操作 请问有什么方法,求大神指教.谢谢了. 解决方案 http://m.baidu.com/from=1011267h/bd_page_type=1/ssid=0/uid=0/pu=usm%400%2Csz%401321_1004%2Cta%40utouch_2_4.1_11_2.1/baiduid=974ADEE1