博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
wikioi--1044 拦截导弹
阅读量:4987 次
发布时间:2019-06-12

本文共 1299 字,大约阅读时间需要 4 分钟。

题目链接:

题目其实就是最长上升子序列的变形。

下面是两个重要定理:

定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小。则X可以被划分成r个但不能再少的反链。 其对偶定理称为Dilworth定理:

定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小。则X可以被划分成m个但不能再少的链。

 

这样问题的第一问是问一套系统最多能拦截多少个导弹,题目意思是每次不能超过上一次的高度,那么也就是求序列中最长不上升的子序列,代码中用的是O(n^2)的经典算法。

第二问呢,最少得要多少套系统才能拦截所有导弹,根据定理,最长上升子序列的长度对应的就是反链的最少个数,也就是最少的系统数。

代码实现采用的是O(nlogn)的算法,

 

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 using namespace std;11 12 vector
data;13 int dp1[10000];14 int dp2[10000];15 int main()16 {17 int tmp;18 while(scanf("%d",&tmp)!=EOF)19 {20 data.push_back(tmp);21 }22 int n = data.size();23 dp1[0] = 1;24 int ans = 1;25 int i;26 for(i = 1; i < n ; ++i)27 {28 int _max;29 _max = 0;30 for(int j = 0 ; j < i ; ++j)31 {32 if(data[j] > data[i])33 {34 _max = max(_max,dp1[j]);35 }36 }37 dp1[i] = _max+1;38 ans = max(ans,dp1[i]);39 }40 cout<
<
dp2[ans])48 {49 dp2[++ans] = data[i];50 }51 else52 {53 int low = 1;54 int high = ans;55 int mid;56 while(low <= high)57 {58 mid = (low + high)/2;59 if(data[i] > dp2[mid])60 {61 low = mid+1;62 }63 else64 {65 high = mid-1;66 }67 }68 dp2[low] = data[i];69 }70 }71 cout<
<

 

转载于:https://www.cnblogs.com/cane/p/3778908.html

你可能感兴趣的文章
telnet命令 测试端口连接是否正常
查看>>
数据库 sharding
查看>>
Java中long和Long有什么区别 (转载)
查看>>
HDU4336 Card Collector(期望 状压 MinMax容斥)
查看>>
P2590 [ZJOI2008]树的统计
查看>>
09:矩阵乘法
查看>>
【第一周】进度条
查看>>
Hibernate 异常:“@OneToOne or @ManyToOne on XXX references an unknown entity: XXX”
查看>>
Activity之多启动图标
查看>>
UVa 11825 (状压DP) Hackers' Crackdown
查看>>
http://localhost:8080/默认访问root项目
查看>>
pseudo-class与pseudo-element的不同点与相同点
查看>>
怎么在SQL查询的结果里加行号?
查看>>
hdu1400Mondriaan's Dream
查看>>
数学题
查看>>
ios IAP 内购验证
查看>>
Linux 各个版本之间的差别
查看>>
urlparse模块
查看>>
M2Mqtt is a MQTT client available for all .Net platform
查看>>
关于ZedGraph几个难点
查看>>