HDOJ1087解题报告【动态规划】
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1087
题目概述:
求所有的严格上升子序列的最大和。
大致思路:
有点类似于求最长上升子序列。
用DP解决。
令f[i]表示前i个数中所有严格上升子序列的最大和,转移方程为:
边界条件为f[i]=a[i].
复杂度分析:
很容易看出DP的复杂度为O(n²),总复杂度为O(T*n²)
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <ctime> 7 #include <map> 8 #include <queue> 9 #include <cstring> 10 #include <algorithm> 11 using namespace std; 12 13 #define sacnf scanf 14 #define maxn 1010 15 #define inf 1061109567 16 #define Eps 0.001 17 #define PI 3.1415927 18 #define mod 1000000007 19 void Swap(int &a,int &b) {int t=a;a=b;b=t;} 20 int Abs(int x) {return (x<0)?-x:x;} 21 typedef long long ll; 22 23 ll f[maxn]; 24 25 int a[maxn]; 26 27 int main() 28 { 29 //freopen("data.in","r",stdin); 30 //freopen("data.out","w",stdout); 31 //clock_t st=clock(); 32 int n; 33 while(scanf("%d",&n),n) 34 { 35 ll ans=0; 36 for(int i=1;i<=n;i++) 37 { 38 scanf("%d",&a[i]); 39 f[i]=a[i]; 40 } 41 for(int i=1;i<=n;i++) 42 { 43 for(int j=1;j<i;j++) 44 { 45 if(a[i]>a[j]) 46 { 47 if(f[i]<f[j]+a[i]) f[i]=f[j]+a[i]; 48 } 49 } 50 ans=max(ans,f[i]); 51 } 52 printf("%lld\n",ans); 53 } 54 //clock_t ed=clock(); 55 //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC); 56 return 0; 57 }