nyoj 79 导弹拦截 & hdu 1257 最少拦截系统
nyoj 79 导弹拦截
1 #include<stdio.h>
2
3 int main()
4 {
5 int n,m,i,j,max,h[21],dp[21];
6 scanf("%d",&n);
7 while(n--)
8 {
9 max=0;
10 scanf("%d",&m);
11 for(i=0;i<m;i++)
12 {
13 scanf("%d",&h[i]);
14 dp[i]=1;
15 }
16
17 for(i=m-2;i>=0;i--)
18 {
19 for(j=i+1;j<m;j++)
20 {
21 if(h[i]>h[j] && dp[i]<dp[j]+1)
22 dp[i]=dp[j]+1;
23 }
24 if(dp[i]>=max) max=dp[i];
25 }
26 printf("%d\n",max);
27 }
28 return 0;
29 }
hdu 1257 最少拦截系统
问题描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统
输入
输入若干组数据.每组数据包括:导弹总个数(正整数),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)
输出
对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统
样例输入
8 389 207 155 300 299 170 158 65
样例输出
2
作这个题时严重受到上一个题的影响,认为若使用的系统数最少则每一套系统应拦截的导弹数尽可能的多,这样的想法是不对的,因为上一个题的要求是全局最优(一套系统尽可能多的拦截导弹),但是本题不但要全局最优(用的系统数最少)还要保证局部安全(不能放过任何一颗导弹).举一个反例,对于长为7的高度序列“7 5 4 1 6 3 2”, 最长不增序列为“7 5 4 3 2”,用多次求最长不上升序列的结果为3套系统;但其实只要2套,分别击落“7 5 4 1”与“6 3 2”。所以本体需要一种"贪心"的策略来保证局部安全.先给出代码.
1 #include<stdio.h>
2
3 int main()
4 {
5 int n,tot,i,j,t,h[1005];
6 while(scanf("%d",&n)!=EOF)
7 {
8 scanf("%d",&t);
9 h[0]=t; tot=1;
10 for(i=1;i<n;i++)
11 {
12 scanf("%d",&t);
13 for(j=0;j<tot;j++)
14 if(t<h[j])
15 {
16 h[j]=t;
17 break;
18 }
19 if(j>=tot) h[tot++]=t;
20 }
21 printf("%d\n",tot);
22 }
23 return 0;
24 }
对于本体的高度序列h,若h[i]大于之前的任何元素,则必须新增一套系统,拦截之后该系统的最大高度为h[i].若h[i]不全大于之前的任意元素,则应选取恰比其大的系统拦截它,拦截之后系统的高度降为h[i].在程序中一次读入导弹高度数据,若其大于之前的任意高度将其放入数组h并将系统数量+1,否则找到当前系统中大于其高度最小的并替换.在构建h数组的过程中h数组自然升序.在查找时也可使用二分法提高效率.