动态规划——导弹拦截

拦截导弹1
Time Limit: 1000 MS Memory Limit: 1000 KB

Description

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

Input

第一行输入M表示包含M组测试数据,每组第一个输入N (N<100)表示后面有N个整数,表示导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)。

Output

对于每组输入数据,第一行输出这套系统最多能拦截多少导弹。

Sample Input

2
7 300 250 275 252 200 138 245
7 181 205 471 782 1033 1058 1111

Sample Output

5
1

解法描述:设导弹序列为x1、x2、x3...xn;拦截序列为y1、y2、y3....yk

设d(i)表示,拦截第i个导弹后,还能拦截的导弹数量(包含第i个)。则我们不难推知d(n)=1;设xm为导弹序列中的最小值,则d(m)=1;然后由已知推未知,从后向前依次推进。

#include
using namespace std;
int main() {
	int T, N;                //T组,每组N个
	cin >> T;               //组数
	for (int i = 0; i < T; i++) {
		cin >> N;           //要拦截的导弹数量
		int* d = new int[N]; //d[i]表示拦截第i个导弹后,最多还能拦截的导弹数量(包括第i个)
		int* x = new int[N]; //x[i]表示第i个导弹的高度

		for (int i = 0; i < N; i++) {
			cin >> x[i];
			d[i] = 1;     //d[i]初始化为1
		}

		for (int i = N - 2; i >= 0; i--) {  //从后向前,开始依次计算最长子序列(由已知推未知)
			for (int j = i + 1; j < N; j++) {   //循环向后,确保找到最长
				if (x[i] > x[j] && d[i] < d[j] + 1) 
				{ d[i] = d[j] + 1; }
				//如果第j个导弹高度低于第i个,则d[i]>=d[j]+1;依次向后循环,直到找到最大的d[j]+1,将其赋值为d(i)
			}
	 }
		int max=0;
	for (int i = 0; i < N; i++) {
		if (d[i] > max) { max = d[i]; }   //找到最大的D[i]进行输出
	}
		cout << max<

补充:

输出如果要拦截所有导弹最少要配备多少套这种导弹拦截系统

Sample Input

2
7 300 250 275 252 200 138 245
7 181 205 471 782 1033 1058 1111

Sample Output

5 2
1 7

依然是动态规划,只是与前者相比判断方式发生了改变,之前是if(x[i]>x[j]&&d[i]

现在改为if(x[i]

多创建一个数组d2【】,d2[i]表示该导弹可被第几套系统拦截

#include
using namespace std;
 int main() {
	int T, N;                //T组,每组N个
	cin >> T;               //组数
	for (int i = 0; i < T; i++) {
		cin >> N;           //要拦截的导弹数量



		//动态规划
		int* d1 = new int[N]; //d1[i]表示拦截第i个导弹后,最多还能拦截的导弹数量(包括第i个)
		int* d2 = new int[N]; //d[2]表示该导弹可被第几套系统拦截
		int* x = new int[N]; //x[i]表示第i个导弹的高度

		for (int i = 0; i < N; i++) {
			cin >> x[i];
			d1[i] = 1;     //d[i]初始化为1
			d2[i] = 1;    
		}
		for (int i = N - 2; i >= 0; i--) {  //从后向前,开始依次计算最长子序列(由已知推未知)
			for (int j = i + 1; j < N; j++) {   //循环向后,确保找到最长
				if (x[i] > x[j] && d1[i] < d1[j] + 1)
				{
					d1[i] = d1[j] + 1;
				}
				else if(x[i] < x[j] && d2[i] < d2[j] + 1){
					d2[i] = d2[j] + 1;
				}

				//如果第j个导弹高度低于第i个,则d[i]>=d[j]+1;依次向后循环,直到找到最大的d[j]+1,将其赋值为d(i)
			}
		}
		int max = 0;
		int num = 0;
		for (int i = 0; i < N; i++) {
			if (d1[i] > max) { max = d1[i]; }
			if (d2[i] > num) { num = d2[i]; }
		}

		cout << max<<" "<< num<< endl;  //循环后d[0]对应的一定是其最长子序列
	}
	
	return 0;
}

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