PKU 1836 Alignment 解题报告

来源:互联网 发布:音乐识别软件 编辑:程序博客网 时间:2024/06/03 21:38
贴道DP的。
  1. /*
  2.   Title: Alignment
  3.   Author: Jeff
  4.   Time:  2008/11/3
  5.   Complexity: O(N^2);
  6.   Result: 328K  32MS/ AC
  7.   Reference: 
  8.         Discuss      
  9.   Description: 
  10.         给定n个人高度,将n个人中的其中一些人出队,使得任何一个人
  11.         都能够看到左无穷远或右无穷远。(高度要大于才能望过去) 。求
  12.         出队的最少人数。 
  13.   Tips:
  14.         虽然是从中间出对,但是可以看成是: 
  15.         最长递增子序列up[] + 逆序的最长递增子序列[down]
  16.         用n^2求出两个子序列后,我犯了一个错误,就是直接用
  17.         n - max{up[i]+ down[i] -1| 0<=i<n)求出来。 
  18.         但是看看以下的反例
  19.         3 4 5 1 2 5 4 3 
  20.         用上面求出来是 3!WA!
  21.         所以用n^2改正:
  22.         n - max{up[i]+down[j]} | 0 <= i < j < n}
  23.         求出结果2. 
  24.         看来此题通过率不高也是有道理的。 
  25.   p.s. 
  26. */
  27. #include <cstdio>
  28. #include <cstring>
  29. using namespace std;
  30. const int MAX = 1000;
  31. double h[MAX];
  32. int up[MAX];
  33. int down[MAX];
  34. int main(){
  35.     freopen("in.txt""r", stdin);
  36.     freopen("out.txt""w", stdout);
  37.     int n;
  38.     while(scanf("%d", &n) != EOF){
  39.         for(int i = 0; i < n; i++)scanf("%lf", &h[i]);
  40.         up[0] = 1;
  41.         for(int i = 1; i < n; i++){
  42.             up[i] = 1;
  43.             for(int j = i - 1; j >= 0; j--){
  44.                 if(h[i] > h[j] && up[j] + 1 > up[i])
  45.                     up[i] = up[j] + 1;
  46.             }    
  47.         }
  48.         
  49.         down[n-1] = 1;
  50.         for(int i = n - 2; i >= 0; i--){
  51.             down[i] = 1;
  52.             for(int j = i + 1; j < n; j++){
  53.                 if(h[i] > h[j] && down[j] + 1 > down[i])
  54.                     down[i] = down[j] + 1;    
  55.             }    
  56.         }
  57.         //for(int i = 0; i < n; i++)printf("%d ", up[i]);printf("/n");
  58.         //for(int i = 0; i < n; i++)printf("%d ", down[i]);printf("/n");
  59.         int ans = 0;
  60.         for(int i = 0; i < n; i++)
  61.             for(int j = i + 1; j < n; j++)
  62.                 if(ans < up[i] + down[j])
  63.                     ans = up[i] + down[j];
  64.         printf("%d/n", n - ans);
  65.     }
  66.     return 0;    
  67. }

原创粉丝点击