zoukankan      html  css  js  c++  java
  • poj_1836 动态规划

    题目大意

        N个士兵排成一排,不是按照高度顺序排列。现在想要从中去掉几名士兵,从而使得队伍中剩余的士兵能够看到这排最左边或者最右边的那个士兵,某士兵能够看到最左边(或最右边)的士兵指这名士兵和最左边(或最右边)士兵之间没有另外一名士兵的高度大于等于这名士兵。

    题目分析

        典型的最长xx子序列问题,能够满足要求的队列有四种: 
    (1)严格上升子序列 
    (2)严格下降子序列 
    (3)以某个士兵为中心,左边上升,右边下降子序列 
    (4)以士兵i左边为上升子序列,士兵j右边为下降子序列,且i在j左边。
    然后排成上述四种队形,找满足某个队形要求的最大的队列中人数。

    实现(c++)

    #include<stdio.h>
    #include<iostream>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<list>
    #include<set>
    #include<set>
    #include<map>
    #include<functional>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    double height[1005];
    int dp_inc[1005]; //从最左边到达i处,以i结尾的最长上升子序列长度
    int dp_dec[1005]; //从i到达最右边,以i开头的最长下降子序列长度
    int Solve(int n){
    	for (int i = 0; i < n; i++){
    		dp_inc[i] = 1;
    		for (int j = i - 1; j >= 0; j--){
    			if (height[j] < height[i]){
    				dp_inc[i] = max(dp_inc[i], dp_inc[j] + 1);
    			}
    		}
    	}
    	for (int i = n - 1; i >= 0; i--){
    		dp_dec[i] = 1;
    		for (int j = i + 1; j < n; j++){
    			if (height[j] < height[i]){
    				dp_dec[i] = max(dp_dec[i], dp_dec[j] + 1);
    			}
    		}
    	}
    	int result = 0;
    	for (int i = 0; i < n; i++){ //选择左侧上升,右侧下降
    		for (int j = i; j < n; j++){
    			result = max(result, dp_inc[i] + dp_dec[j] - (i == j));//如果i和j重合,则去掉重合的一次
    		}
    	}
    	return result;
    }
    int main(){
    	int n;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++){
    		scanf("%lf", &height[i]);
    	}
    	int result = Solve(n);
    	printf("%d
    ", n - result);
    	return 0;
    }
    
  • 相关阅读:
    JSF大概介绍
    专门用于swing显示的工具类
    oracle 中查某表的所有列字段
    从实例谈OOP、工厂模式和重构
    C#中结构或类的嵌套 的方法
    怎样成为优秀的软件模型设计者
    Asp.NET编程时的几个小技巧
    在.net安装程序中部署oracle客户端全攻略
    在.NET中调用Oracle9i存储过程经验总结
    使用JNDI的一个容易忽略的错误
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4840846.html
Copyright © 2011-2022 走看看