POJ 1836 Alignment (简单DP)

来源:互联网 发布:linux连接数据库命令 编辑:程序博客网 时间:2024/04/30 12:35

题目大意

  • 给出n个浮点数(2 <= n <= 1000 , 0.5 <= 浮点数 <=2.5),然后求一段序列长度ans,要求这个序列中从左到右递增,或者从右到左递增。输出n - ans

分析

  • 求最长上升子序列和最长下降子序列的长度
  • dp1[i]表示以i结尾的最长上升子序列的长度
  • dp2[i]表示以i结尾的最长下降子序列的长度
  • 然后枚举两段区间[0,i] [j,n-1]
  • 时间复杂度O(n^2)

代码

#include <iostream>using namespace std;const int maxn = 1010;double num[maxn];int dp1[maxn] = {1}; // dp1[i]表示以i结尾的最长上升子序列的长度int dp2[maxn] = {1}; // dp2[i]表示以i结尾的最长下降子序列的长度int main(){    int n;    while(cin >> n)    {        for(int i = 0; i < n; i++) cin >> num[i];        for(int i = 1; i < n; i++) { //LIS            dp1[i] = 1;            for(int j = 0; j < i; j++) if(num[j] < num[i]) dp1[i] = max(dp1[i] , dp1[j]+1);        }        dp2[n-1] = 1;        for(int i = n-2; i >= 0; i--) { //LDS            dp2[i] = 1;            for(int j = n-1; j > i; j--) if(num[j] < num[i]) dp2[i] = max(dp2[i] , dp2[j]+1);        }        int ans = 0;        for(int i = 0; i < n; i++) {  //枚举起点[0,i]  [j,n-1]            ans = max(ans , dp1[i]);            for(int j = i+1; j < n; j++) ans = max(ans , dp1[i]+dp2[j]);        }        cout << n - ans << endl;    }    return 0;}
0 0
原创粉丝点击