附上代码
#include<stdio.h>
int a[100002];
int dp[100002];//用于动态规划的数组
int dp2[100002];
int cnt = 0;//计数器
int max(int x,int y)
{
return (x > y) ? x : y;
}
int main()
{
int result1 = 1;
int result2 = 1;
while(scanf("%d",&a[cnt])!=EOF)//将数据输入数组
{
cnt++;
}
dp[0] = 1;
dp2[0] = 1;
for(int i = 1;i < cnt;i++)//求最长不上升子序列 和最长上升子序列
{
dp[i] = 1;
dp2[i] = 1;
for(int p = i - 1;p >= 0;p--)//动归主体
{
if(a[i] <= a[p])
dp[i] = max(dp[i],dp[p] + 1);
if(a[i] > a[p])
dp2[i] = max(dp2[i],dp2[p] + 1);
}
result1 = max(result1,dp[i]);
result2 = max(result2,dp2[i]);
}
printf("%d\n%d",result1,result2);
return 0;
}
删除线格式
这道题是一道要两次使用动态规划的题目,第一次使用很明显,是求一个导弹拦截设备最多能拦截多少导弹,就是求数组的最长不上升子序列的长度 ,第二次比较难看出来,求最少要用多少个拦截装置才能拦截所有导弹,就是要求不上升子序列的个数
这里要补充一下 不上升子序列的个数等于最长上升子序列的长度
将问题变成了求最长上升子序列的长度,这道题的解题方法就很清晰了。
还有一点需要注意的是,我在写输入函数的时候开始是这样写的
scanf("%d",&a[cnt++]);
char b = getchar();
while(b != '\n')
{
scanf("%d",a[cnt++]);
b = getchar();
}
我用数字后面是空格还是回车来判断输入是否结束,这样的做法在dev上是可以正常运行的,但是在洛谷的oj上就会变成死循环,需要换成以开始题解上给的输入方法,会全篇tle了。
这到题的时间复杂度是n2,所以只能拿一百分,想要拿到200分就要写出复杂度为n*logn的算法。
溜了溜了