HDU—1231 最大连续子序列
写给自己,还是要多学啊,太年轻了
一个简单的DP,很经典,最最最最最主要的就是状态转移方程、
这个的就是
sum【i】=max(sum【i-1】+arr【i】,arr【i】);
arr是储存数组,sum【i】是代表结尾是第i的元素的最大序列和;
然后遍历数组找到最大值,记下下标(endvalue),找开头的(beginvalue)就从结尾endvalue开始用最大值去减去每个元素,,然后直到减到0;
剩下的这里说一些细节
1.把max2设为-1;
如果max2==0,全输出0即可,因为数列里至少有一个0存在
2.如果max2<0,那么整个数列全为负数,输出 0 、arr【0】和arr【n-1】
代码块
代码块语法遵循标准markdown代码,例如:
@requires_authorization
#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
//DP最大连续子序列
int main()
{
int arr[10000]={0};
int max1[10000]={0};
int n,i;
while(cin>>n,n){
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
int max2=-2;int beginvalue=0;int endvalue=0;
for(i=0;i<n;i++){
max1[i]=max1[i-1]+arr[i]>arr[i]?max1[i-1]+arr[i]:arr[i];
// 最最重要的状态转移方程
if(max1[i]>max2){
max2=max1[i];
endvalue=i;
}
}int max5=max2;
for(i=endvalue;max5!=0;i--){
max5-=arr[i];
beginvalue=i;
}
if(max2<0){
max2=0;
printf("%d %d %d\n",0,arr[0],arr[n-1]);
continue;
}else if(max2==0){
cout<<"0 0 0"<<endl;
continue;
}
cout<<max2<<" "<<arr[beginvalue]<<" "<<arr[endvalue]<<endl;
}
return 0;
}
... prompt'''