真心感觉自己做这种dp题太难了,看了很久才想通,代码是别人的,自己只是借助自己的理解说说这题
这道题是十分经典的dp题,最大子段和问题,题中给出一段数字串,第一个数表示有几个数字段,第二个数表示
后面即将输出几位数字
这段代码中 数据比较大,输入很多,所以采用c语言中的输入scanf_s用来提高效率,
然后注意 题中的三个数组和一个表示以前最大值的数max_pre;单个字符可自成一个数字段;
思想是 先逐个把各个数相加,取最大的值赋予给当前数组,
并把最大值付给 max_pre;
然后再把最大值付给以前数组;
这样可以把求出各个字段的值,并用max_pre保存住最大的那个;
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
#define MAXN 1000000
int num[MAXN+50],now[MAXN+50],pre[MAXN+50];
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int m,n,i,j,k,ans,max_pre;
while(cin>>m>>n)
{
for(i=1;i<=n;i++)
{
scanf("%d",&num[i]); //数据太多所以用scanf
}
memset(now,0,sizeof(now));
memset(pre,0,sizeof(pre));
for(i=1;i<=m;i++)
{
max_pre=(-1)*(MAXN*90);
for(j=i;j<=n;j++)
//对于每个i,随着j的增大,max_pre越滚越大
{
now[j]=max(now[j-1]+num[j],pre[j-1]+num[j]);
pre[j-1]=max_pre;
if(now[j]>max_pre)
{
max_pre=now[j];
}
}
}
cout<<max_pre<<endl;
//最后一轮的最大值就是答案。 //因为上一个循环中对于每个i,随着j的增大,max_pre越滚越大 //而且pre也是越滚越大的。
}
return 0;
}