动态规划之——又见拦截导弹(nyoj814)

问题描述:

又见拦截导弹

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 3
描述

大家对拦截导弹那个题目应该比较熟悉了,我再叙述一下题意:某国为了防御敌国的导弹袭击,新研制出来一种导弹拦截系统但是这种导弹拦截系统有一个缺陷它的第一发炮弹能够到达任意的高度但是以后每一发炮弹都不能超过前一发的高度。突然有一雷达捕捉到敌国的导弹来袭。由于该系统存在缺陷,所以如果想把所有的导弹都拦截下来,就要多准备几套这样的导弹拦截系统。但是由于该系统成本太高,所以为了降低成本,请你计算一下最少需要多少套拦截系统。

输入
有多组测试数据。
每组数据先输入一个整数N(N≤3000),代表有N发导弹来袭。接下来有N个数,分别代表依次飞来的导弹的导弹的高度。当N=-1时表示输入结束。
输出
每组输出数据占一行,表示最少需要多少套拦截系统。
样例输入
8
389 207 155 300 299 170 158 65
5
265 156 123 76 26
样例输出
2
1

分析:此题依然是动态规划问题,可以用动态规划的思想记录下每个阶段的最优解:有1个导弹来袭需要几个装置;有2个导弹来袭,需要几个装置;……有n个导弹来袭,需要几个装置。这样有小到大的分析,即得最终问题的最优解。

动态规划的解法:(40ms)

#include<stdio.h>
int main()
{
    int n,i,j,c,a[3000],dp[3000];
    while(1)
    {
        scanf("%d",&n);
        if(n==-1)break;
        for(i=0;i<n;i++) scanf("%d",&a[i]);
		dp[0]=a[0]; c=1; 
		for(i=1;i<n;i++)
		{
			for(j=0;j<c;j++)
			if(a[i]<=dp[j])
			{
				dp[j]=a[i];
				break;
			}
			if(j>=c){dp[j]=a[i]; c++;}
        }
        printf("%d\n",c);
    }
    return 0;
}        


普通解法:对n个 导弹进行多次遍历,每次找一个最小值,按最小值找一个最长非递减序列,全部处理,每处理一个n--,表示还有n个未处理;每对这n个导弹遍历一遍需要的装置个数cnt++;

 
 
 
#include <stdio.h>
int main()
{
	int n,s[3005]={0};
	while(scanf("%d", &n)&&n !=-1)
	{
		for(int i=0; i<n; i++)
		scanf("%d", &s[i]);
		int cnt=0, k=n,pre;
		while(k)
		{
			pre=0;
			for(int i=n-1; i>=0; i--)
			{
				if(s[i]>=pre){
					pre = s[i];
					s[i] = -1;
					k--;
				}
			}
			cnt++;
		}
		printf("%d\n", cnt);
	}
	return 0;
}

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=814

你可能感兴趣的:(动态规划)