最大递增子序列问题
状态:dp[i]:前i个数当中,以a[i]为结尾所能构成的最大递增子序列的各数字之和;
状态转移方程在代码中解释
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define inf 1000000000000
using namespace std;
long long dp[1005],a[1005];
int main()
{
int n,i,j;
long long temp,ans;
while(~scanf("%d",&n)&&n)
{
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
ans=dp[1]=a[1];
for(i=2;i<=n;i++)
{
temp=-inf;
for(j=i-1;j>=1;j--)
{
if(a[j]<a[i]) //找出1-i-1之间,最大的那个递增序列,但前提是要保证递增
{
if(dp[j]>temp)
temp=dp[j];
}
}
if(temp==-inf||temp<0) //temp=-inf表示没找着,temp<0表示此时前面最大递增序列和是负数,这时不能将a[i]加上去,这样只会让a[i]更小
dp[i]=a[i];
else dp[i]=a[i]+temp;
if(ans<dp[i])
ans=dp[i];
}
printf("%lld\n",ans);
}
return 0;
}
突破口:dp[i]要在保证递增的情况下,在前i-1个中挑选出最大的子序列。