http://acm.hdu.edu.cn/showproblem.php?pid=1087
分析:
这是很典型的可以用DP求解的问题,且具有明显的非贪心选择性质。
输入一组数字,只能由小数跳到大数。问最终能取得的路径上数字和是多少。
特例就是:4 3 3 2 1,结果为3。
定义状态方程:sum[i]表示从前往后在第i个棋子上所能取得的最大路径和。则一开始sum[i]=a[i];
定义max_sum作为之前已经取得的路径和,sum[j]+a[i]作为新的可能取得的路径和,二者中的最大值就是sum[i]的取值。
如:2 3 5 4 6,从前到后sum[i]依次为:2 5 10 9 ,在求sum[4]时,max_sum的变化为:6,6<9+6—>15,15<10+6—>16.
其中max_element作为STL中的内容,作用是返回数组中最大值所在的地址,所以*max_element可以读取出最大值。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000;
int a[maxn];
int sum[maxn];
int main(void)
{
int T;
int n,m;
int i,j,k;
while(cin>>T)
{
if(T==0) break;
memset(sum,0,sizeof(sum));
for(i=0;i<T;i++) cin>>a[i];
for(i=0;i<T;i++)
{
int max_sum=a[i];
for(j=i-1;j>=0;j--)
{
if(a[j]<a[i]) //只有在可以跳转的时候才有必要比较
max_sum=max(max_sum,sum[j]+a[i]); //进行更新
}
sum[i]=max_sum;
}
cout<<*max_element(sum,sum+T)<<endl;
}
}