http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28415#problem/F

题目大意:有n个士兵排成一列,将军想从中抽出最少人数使队伍中任何士兵都能够看到左边最远处或右边最远处

解题思路:①此题是最长上升子序列的升级版。

②这里先介绍一下最长上升子问题(LIS):给定n个数从右往左选出尽量多的数,组成一个上升子序

列,相邻的不能相等 ——> 设d[i]表示以第i个数结尾的最长上升子序列,则状态转移方程为:d[i]=

max{0,d[j]|j<i,a[j]<a[i]},答案是max{d[i]};

③此题可从左往右求出d[](代码里为b[]),再从右往左求出d[](代码里为c[]),答案就是max{b[i]+c[j]

| i<j}

#include<iostream>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
int main(){ double a[];
int b[],c[]; for(int n;cin>>n&&n;){ for(int i=;i<n;i++){ //输入身高数据a[]并正向计算以第i个结尾的LIS对应为b[i]
cin>>a[i];
int max=-;
for(int j=;j<i;j++){
if(a[i]>a[j]&&b[j]>max){
max=b[j];
}
}
if(max==-)b[i]=;
else b[i]=max+;
}
for(int i=n-;i>=;i--){ //逆向计算以第i个结尾的LIS对应为c[i]
int max=-;
for(int j=n-;j>i;j--){
if(a[i]>a[j]&&c[j]>max){
max=c[j];
}
}
if(max==-)c[i]=;
else c[i]=max+;
} double maxtotal=-; //计算b[i]+c[j] && i<j 的最大值
for(int i=;i<n;i++){
for(int j=n-;j>i;j--){
int sum=b[i]+c[j];
if(sum>maxtotal){
maxtotal=sum;
}
}
} cout<<n-maxtotal<<'\n'; //输出挑出的最少人数
}return ;
}

最新文章

  1. C/C++头文件使用 #ifndef #define #endif 的原因
  2. CPU与内存的那些事
  3. PAT 1024. 科学计数法 (20)
  4. Android 开发错误信息001
  5. iOS 图片拉伸的解释
  6. winform 发邮件
  7. Python的简介以及安装和第一个程序以及用法
  8. usb.ids
  9. Google网页搜索
  10. 广州Uber优步司机奖励政策(1月25日~1月31日)
  11. java对Ldap操作4
  12. Codeforces 549H. Degenerate Matrix 二分
  13. 每个前端开发者必会的 20 个 JavaScript 面试题
  14. mongodb管理与安全认证
  15. CUDA 例程
  16. Android下载管理DownloadManager功能扩展和bug修改
  17. Golang面向对象编程-struct(结构体)
  18. Unity -----一些可能存在的错误
  19. 【Java并发编程】之九:死锁
  20. 【JVM】调优笔记3-----JVM参数配置 JDK1.8

热门文章

  1. 一个CURL
  2. 一个sendMessage
  3. Trie树(c++实现)
  4. eclipse开发 javafx(转)
  5. zTree+EasyUi做权限遇到的小问题
  6. Redis多机常用架构-主从
  7. IB交换机配置命令总结
  8. git svn clone时间估算
  9. Cassandra对读写请求的处理机制
  10. Linux初记