【原創】【NOIP1999】攔截導彈
阿新 • • 發佈:2019-02-13
[NOIP1999]攔截導彈
時間限制: 1 Sec 記憶體限制: 64 MB提交: 666 解決: 233
題目描述
某國為了防禦敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。 輸入導彈依次飛來的高度,計算這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。輸入
第1行:依次輸入若干個導彈的高度H(1≤H≤30000),導彈的個數N≤5000
輸出
第1行:一個整數,表示單枚炮彈能攔截多少導彈 第2行:一個整數,表示攔截所有導彈最少要配備多少套這種導彈攔截系統
樣例輸入
389 207 155 300 299 170 158 65
樣例輸出
62提示
第2問最直觀的演算法是貪心,但是反例也容易找到,如: 6 5 1 7 3 2 如果第一次打6 5 3 2,顯然還要打兩次,而最好的方案是6 5 1/7 3 2。這是一道很經典的題目,題裡涵蓋了對動歸,搜尋,貪心的考察。那麼,就讓我們好好地來分析分析這道題目吧。 這道題目有兩個小問。先來看看第一個小問。 我在題目中用紅色標記出了一些關鍵資訊,透過這些資訊,我們可以發現,這個炮彈是從高往低掉,看來我們要找“最長下降序列”?不不不,再看看那幾個紅得發黃
#include<cstdio>
#include<algorithm>
using namespace std;
int n=1,a[6006],da=-1,db,yx,f[6006],much;
void preparation()
{
while(scanf("%d",&a[n])!=EOF) n++;
n--;
}
void step_one()
{
for(int i=1;i<=n;i++)
{
int e=0;
for(int j=1;j<i;j++)
if(a[j]>=a[i] and e<f[j]) e=f[j];
f[i]=e+1;
if(da<f[i]) da=f[i],db=i;
}
printf("%d\n",da);
}
void step_two()
{
much=a[1],yx=0;
for(int i=1;i<=n;i++)
if(a[i]>=0)
{
much=a[i];
for(int j=i+1;j<=n;j++)
if(a[j]>=0 and a[j]<=much)
much=a[j],a[j]=-66;
yx++;
}
printf("%d",yx);
}
int main()
{
preparation();
step_one();
step_two();
}