最长上升非降子序列的长度动态规划
第一种dp从后往前:
dp[i]表示以a[i]为起点的最长上升非降子序列的长度
a[8]={10,2,2,4,12,23,34,2}
dp[8]={4,6,5,4,3,2,1,1};
代码实现:
1 #include<bits/stdc++.h> 2 using namespace std; 3 void logest_increase_sub(const int*a,int ssize) 4 { 5 int *dp=new int[ssize](); 6 int *p=new int[ssize](); 7 //dp[ssize-1]=1; 8 for(int i=ssize-1;i>=0;i--) 9 { 10 int maxn=0,index=0; 11 for(int j=i+1;j<ssize;j++) 12 { 13 if(a[i]<=a[j]&&maxn<dp[j]) 14 { 15 maxn=dp[j]; 16 index=j; 17 } 18 } 19 if(maxn==0) 20 { 21 dp[i]=1; 22 p[i]=-1; 23 } 24 else 25 { 26 dp[i]=maxn+1; 27 p[i]=index;//记录索引 28 } 29 } 30 int max_sum=0,max_index=0; 31 for(int i=0;i<ssize;i++) 32 { 33 cout<<dp[i]<<" "; 34 if(max_sum<dp[i]) 35 { 36 max_sum=dp[i]; 37 max_index=i; 38 } 39 } 40 cout<<endl; 41 printf("最长子序列长度: %d\n",max_sum); 42 for(int i=max_index;i!=-1;i=p[i]) 43 { 44 cout<<a[i]<<" "; 45 } 46 cout<<endl; 47 delete[]dp; 48 delete[]a; 49 } 50 int main() 51 { 52 int ss[]={1,2,4,1,3}; 53 logest_increase_sub(ss,5); 54 return 0; 55 }
第二dp从前往后:
dp[i]表示以a[i]为终点的最长上升非降子序列的长度
a[8]={10,2,2,4,12,23,34,2}
dp[8]={1,1,2,3,4,5,6,3};
代码实现:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int a[100],dp[100],p[1000],n,i,j,k,index; 6 cin>>n; 7 int maxn=0; 8 for(i=0;i<n;i++) 9 cin>>a[i]; 10 memset(dp,0,sizeof(dp)); 11 memset(p,-1,sizeof(p)); 12 dp[0]=1; 13 14 for(i=0;i<n;i++) 15 { 16 maxn=0;index=-1; 17 for(j=i-1;j>=0;j--) 18 { 19 if(a[j]<=a[i]&&dp[j]>maxn) 20 { 21 maxn=dp[j]; 22 index=j; 23 } 24 } 25 if(maxn==0) 26 { 27 dp[i]=1; 28 p[i]=-1; 29 } 30 else 31 { 32 dp[i]=maxn+1; 33 p[i]=index; 34 } 35 } 36 for(i=0;i<n;i++) 37 cout<<dp[i]<<" "; 38 cout<<endl; 39 maxn=0; 40 int max_index=-1; 41 for(i=0;i<n;i++) 42 { 43 if(dp[i]>maxn) 44 { 45 maxn=dp[i];max_index=i; 46 } 47 } 48 printf("最长子序列长度: %d\n",maxn); 49 for(i=max_index;i!=-1;i=p[i]) 50 cout<<a[i]<<" ";//因为是从前往后的dp所以索引是逆序的 51 cout<<endl; 52 return 0; 53 }