洛谷P1020 导弹拦截 n2算法 C语言题解

附上代码

#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的算法。
溜了溜了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值