openjudge2757 & openjudge2945 最长上升子序列&最长非升子序列(DP入门)
2757:
状态转移方程:
MaxLen(1) = 1
MaxLen(k) = Max{MaxLen(i):1<=i<=k && a[i]<a[k] &&k!=1} +1
这个状态转移方程的意思就是,MaxLen(k)的值,就是在a[k]左边,终点数值小于a[k],且长度最大的那个上升子序列的长度再加1。因为a[k]左边任何终点数小于a[k]的子序列,加上a[k]后就能形成一个更长的子序列。
代码:
#include<stdio.h> int a[1010]; int b[1010]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } b[1]=1; for(int i=2;i<=n;i++) { int temp=0; for(int j=1;j<i;j++) { if(a[j]<a[i]&&temp<b[j]) { temp=b[j]; } } b[i]=temp+1; } int max=-1; for(int i=1;i<=n;i++) { if(b[i]>max) { max=b[i]; } } printf("%d\n",max); }
2945:
这题一样……改一符号就成。。。
#include<stdio.h> int a[1010]; int b[1010]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } b[1]=1; for(int i=2;i<=n;i++) { int temp=0; for(int j=1;j<i;j++) { if(a[j]>=a[i]&&temp<b[j]) { temp=b[j]; } } b[i]=temp+1; } int max=-1; for(int i=1;i<=n;i++) { if(b[i]>max) { max=b[i]; } } printf("%d\n",max); }