合唱队形---最长上升子序列变形

来源:互联网 发布:黑客要学什么编程语言 编辑:程序博客网 时间:2024/05/20 18:43

http://www.rqnoj.cn/Problem_26.html

一、思路

感觉自己好笨

虽然知道是求两次最长上升子序列,一边上升,一边下降

我愣是理解成了,写两个,都是顺序来,一个是求顺序的最长上升

一个是顺序的最长下降


怎么调试都是20-40个得分点

郁闷了

-----------------

求两次 成开口向下的抛物线

顺序求上升

逆序求上升

然后求max(aUp[i] + aReverseUp[i] - 1) 其中1<=i<=n


时间复杂度NlogN


总结:想清楚了再写,不要想到某个点 就去弄,陷于局部

终于AC了


#include <iostream.h>#define MAX 101//二分查找,小于key 的最大f[]的位置jint BinarySearch(int * f, int l, int r, int key){if (l <= r){int mid = (l + r) / 2;if (f[mid] > key){return BinarySearch(f, mid+1, r, key);}else{return BinarySearch(f, l, mid-1, key);}}else{return l;}}//二分查找,大于key的最小f[]的位置jint UpBinarySearch(int *upF,int l, int r, int key){if (l<=r){int mid = (l + r) / 2;if (upF[mid] >= key){return UpBinarySearch(upF,l, mid-1, key);}else{return UpBinarySearch(upF, mid+1, r, key);}}else{return l;}}int main(){int a[MAX];int f[MAX];int aUp[MAX];int aReverseUp[MAX];    int k = 0;//lengthint i = 0, n=0;//loop//读入cin>>n;for (i=1; i<=n; i++){cin>>a[i];}//正着上升求序f[0] = -9999;k = 0;for (i=1; i<=n; i++){if (f[k]<a[i]){f[++k] = a[i];aUp[i] = k;}else{int j = UpBinarySearch(f, 0, k, a[i]);f[j] = a[i];aUp[i] = j;}}//逆着上升排序f[0] = -9999;k = 0;for (i=n; i>=1; i--){if (f[k]<a[i]){f[++k] = a[i];aReverseUp[i] = k;}else{int j = UpBinarySearch(f, 0, k, a[i]);f[j] = a[i];aReverseUp[i] = j;}}//求最长的kk = -1;for (i=1; i<=n; i++){int sum = aUp[i] + aReverseUp[i] - 1;//测试用//cout<<" up:"<<aUp[i]<<" aReverseUp: "<<aReverseUp[i]<<endl;if (k<sum){k = sum;}}//输出要剔除的n-kcout<<n-k;return 0;}



原创粉丝点击