1. 题目源地址:http://acm.hdu.edu.cn/showproblem.php?pid=1231
2. 动态规划方程:
状态:dp[i]:以i为结尾最长连续序列
初始状态:dp[0]=num[0]
状态转移:dp[i]=max{dp[i-1]+num[i],num[i]} (比较已有序列和新元素的和与新元素本身的大小关系,取较大的)
要求最大的,只需从dp[]找出最大值就行了举例说明:序列 {-2, 11, -4, 13, -5, -2}1.初始状态时:dp[0]=num[0]=-22.状态转移:要求dp[1],则需要比较dp[0]+num[1]与num[1]的大小关系。由于 dp[0]+num[1]=-2+11=9,而num[1]=11。所以需要抛弃序列之前保留的值,从num[1]开始重新计数。故状态转移为:dp[1]=num[1]=113.源代码:#include<iostream> using namespace std; int main() { int N,i,j,pos; int num[10010],dp[10010]; int start[10010];//用于记录序列的开始元素 while(cin>>N && N) { for(i=0;i<N;i++) cin>>num[i]; int flag=1; //如果全为负数,输出0以及第一个和最后一个元素 for(i=0;i<N;i++) { if(num[i]>=0) { flag=0; break; } } if(flag) { cout<<0<<" "<<num[0]<<" "<<num[N-1]<<endl; continue; } dp[0]=num[0]; start[0]=0; for(i=1;i<N;i++) { if(dp[i-1]+num[i]>=num[i])//若符合动态规划方程。注意:这里是大于等于! { dp[i]=dp[i-1]+num[i]; start[i]=start[i-1];//序列开始元素的值不变 } else { dp[i]=num[i]; start[i]=i;//序列开始元素的值改变 } } int max=-1;//注意:这里max注意取值 for(i=0;i<N;i++) { if(dp[i]>max) { max=dp[i]; pos=i;//start[pos]中记录了该序列的开始位置,pos为序列的结束 } } cout<<max<<" "<<num[start[pos]]<<" "<<num[pos]<<endl; } return 0; }