某国为了防御敌国的×××袭击,发展出一种×××拦截系统。但是这种×××拦截系统有一个缺陷:
虽然它的第一发炮弹能够达到任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,
雷达捕捉到敌国的×××来袭。由于该系统还在使用阶段,所以只有一套系统,因此有可能不能拦截所有的×××。
输入×××依次飞来的高度(雷达给出高度数据是不大于30000的正整数),计算这套系统最多能拦截多少×××,
如果要拦截所有×××最少要配备多少套这种×××系统。
样例:
Input: 389 207 155 300 299 170 158 65
Output: 6(最多拦截×××数)
2(要拦截所有×××最少要配备的系统数)
很早就看到这个经典的题目,但是一直没有把它的代码出来。一开始的思路是动态规划,步步最优结果最优。开始,我尝试着从后面倒序计算,因为后面的计算要用到前面的结果,所以用数组存储从后面计算的结果,结果越写到后面感觉越乱,越写越复杂。最后还是顺着我的思路写完了。
后来我上网一查才知道,设计的算法不合理,没有充分理解动态规划的解决问题的思想。然后。。。重新认真的分析,参考。。。才明白,子问题和原问题的解间有联系,只需要解决子问题,最后再累加,就问得到原问题的解。。。。
应该好好去理解动态规划。。。
#include <iostream>
using namespace std;
const int MAX = 20;
bool prove(int arr[]);
void solution(int arr[],int *a,int *b); //a为拦截数,b为需要设备数
int main()
{
int arr[MAX] = {0} , i = 0,a = 0,b = 0;
cout << "输入×××高度:(输入0结束) " << endl;
do
{
cin >> arr[i];
i++;
}while(arr[i-1] != 0 && i<MAX);
solution(arr,&a,&b);
cout << "一套设备能够拦截的×××数是: " << a << endl;
cout << "拦截全部×××需要的设备数是: " << b << endl;
system("pause");
return 0;
}
bool prove(int arr[])
{
for(int i = 0;i<MAX;i++)
{
if ( arr[i] != 0)
{
return true;
}
}
return false;
}
void solution(int arr[],int *a,int *b) //输入输出参数,通过引用调用
{
do
{
int min = 0;
for(int i=0;i<MAX;i++)
{
if(arr[i] != 0)
{
min = arr[i];
arr[i] = 0;
break; //直接跳出for循环,不是中止一次!!!
}
}
for(int i=0;i<MAX;i++)
{
if(arr[i] < min && arr[i] != 0 ) //求最长不将序列长度
{
min = arr[i];
arr[i] = 0;
(*a)++; //从i=N方案到i=0方案的求和;递归方案
}
}
(*b)++;
}while(prove(arr));
return;
}
转载于:https://blog.51cto.com/zhgnanjiang/454357