HDU1087 【DP问题之最大递增子段和问题】

 状态方程:dp[j]=max{dp[i]}+a[j]; 其中,0<=i<=j,a[i]<a[j]   

如果求最大值,要有个最小值,不断的更新用DP存所有可能性的组合:

2016.2.18更新:别人的方法终究不是自己的,看不懂乱写还是不会的;

题意:类似于跳棋,只能从低的跳到高的并求最高分数。如:2 1 3 ; 可以选择1->3 四分, 也可以2->3 五分;

就是求:最大递增子段和问题


思路: 从一组数据中找一组递增数列且和为最大,假如我们从最后面往前找,每次都要找出前面比本身的小的数 ,并加上dp[j],就是此时dp[j]最大的值

            用dp[ ]记下相应的位置的最大和,dp[ i ]=max(num[ i ] ,f[ i ]+num[ j ] ),其中0<=j<i且num[ i ]>num[ j ],

            这样就可以求出从开始到第i个元素,递增数列的和的最大值,最存在dp[ i ]中;

#include <bits/stdc++.h>
using namespace std ;
int dp[1005],a[1005];
int n ;
int main()
{
	while(cin>>n,n)
	{
		int max ;
		for(int i = 0 ; i < n ; i++)
		{
			cin>>a[i];
			dp[i]=a[i];
		}
		
		for(int i = 1 ; i <n ; i++)
		{
			
			for(int j =i-1;j>=0;j-- )
			{
				if(a[i]>a[j]&&dp[i]<dp[j]+a[i])
				{
					dp[i]=a[i]+dp[j];
				}
			}
		}
		max = -99999999999;
		for(int i = 0 ; i <n;i++)
		{
			if(dp[i]>max)
			{
				max=dp[i];
			}
		}
		cout<<max<<endl;
	}
}





你可能感兴趣的:(HDU1087 【DP问题之最大递增子段和问题】)