题目=v=
POJ 8780 拦截导弹
其实基本上所有OJ都有233
题解QAQ
那我先讲一下思路?
首先这边这道题应该是某年的提高组(就是高中组)的题目
放在提高组里算是比较简单的了吧=w=
然后。。。容我看下题
第一行表示高度 第二行表示如果我要拦截这第i个导弹,我到第i个最多可以拦截的导弹个数
第三行表示在拦截第i个的条件下,第i个之前我可以拦截到的最多的导弹的序号
【哦哦哦哦我有MarkDown有图表恐惧症!!!
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|
389 | 207 | 155 | 300 | 299 | 170 | 158 | 65 |
1 | 2 | 3 | 2 | 3 | 4 | 5 | 6 |
第一个 | 第二个 | 第一个 | 第四个 | 第五个 | 第六个 | 第七个 | |
1+1 | 2+1 | 1+1 | 2+1 | 3+1 | 4+1 | 5+1 |
第三行是我选择的前一个拦截的导弹
就是说这个时候拦截的要求是前一个导弹高于我现在的导弹
但是这时候会有很多选项
我就需要做出一个选择,使得到在拦截第i个的条件下,我在第1-i个中能拦截到最多的导弹
我举第六个的例子说明一下关于第三行的选择
第六个的高度是158
如果我要拦截第六个,前面可以拦截的导弹都比它高,可以是第1,2,4,5,6个
那么这时候就需要在第1,2,4,5,6个导弹之间做出选择
首先我们来明确选择的目的
我们这次选择是为了让我在拦截到第六个导弹的情况下,在1-6的导弹中能拦截尽可能多的导弹
然后如果我们在拦截第六个导弹前拦截了x个导弹,在拦截第6个导弹时,一共拦截x+1个导弹
所以我们应使x尽可能大
所以我们选择1,2,4,5,6中第二行最大的
最大的是第六个的4
因此我们选择第六个
【能看懂吗?
【其实我就是不会写动态转移方程(/▽\=)
呃。。大概思路就酱
然后关于实现
先读入 用h来储存各个导弹的高度
h[i]表示第i个导弹的高度
再用一个数组a[i]表示上面表(就是上面的那些好像有对齐的数据)中的第二行
a[i]表示拦截到第i个导弹,在拦截第i个导弹的前提下第1-i中醉倒可以拦截到的导弹数
然后我们从第1到第n的a值进行寻找,找出其中的最大值,即为最后的值
感觉自己讲的好抽象QAQ我讲是讲完了 过会儿再写一下代码再补过来QAQ
代码
C++
#include <cstdio>
int main()
{
int n;
int h[16];
scanf("%d",&n);
int a[16];
int max=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&h[i]);
int x=0;
for (int j=1;j<i;j++)
if ((h[i]<=h[j])&&(a[j]>x))
x=a[j];
a[i]=x+1;
if (a[i]>max)
max=a[i];
}
printf("%d",max);
}