2904: 最少拦截系统 基础dp/求不升子序列个数 7654: 拦截导弹/最长不降子序列长度

描述

 

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。怎么办呢?请帮助计算一下最少需要多少套拦截系统?

 

输入

 

输入若干组数据(不超过100组),每组数据一行,分别为:导弹总个数(正整数,不超过1000),导弹依此飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)

 

输出

 

对应每组数据输出拦截所有导弹最少要配备多少套这种导弹拦截系统。

 

样例输入

 8 389 207 155 300 299 170 158 65

样例输出

 2

解题思路
这道题本质上是取最长的递减子序列,然后利用Dilworth定理最少要配备的系统数。

首先对于最长的递减子序列,可以采用深度优先的搜索来获取,或者利用动态规划来计算,状态转移方程是:

其中,下标i表示的是以i为结尾的降序或者升序数列。

之后,利用Dilworth定理,要计算最少的降序子序列,统计最长非递减序列中的元素数目即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[1001],dp[1001];//dp[i]表示到第i个导弹有多少个不升子序列 
 4 int n;
 5 int main()
 6 {
 7     while(cin>>n)
 8     {
 9         memset(dp,0,sizeof(dp));
10         for(int i=1;i<=n;i++)cin>>a[i],dp[i] = 1;
11         dp[1] = 1;
12         for(int i=1;i<=n;i++)
13         {
14             for(int j=1;j<i;j++)
15             {
16                 if(a[i]>a[j])dp[i] = max(dp[i],dp[j]+1);
17             }
18 
19         }
20         int ans = -1;
21         for(int i=1;i<=n;i++)ans = max(ans,dp[i]);
22         cout<<ans<<endl;
23     }
24      return 0;
25 }

 

7654: 拦截导弹

描述

 

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

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹。

 

输入

 

第一行是一个整数N(不超过15),表示导弹数。

第二行包含N个整数,为导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)。

 

输出

 

一个整数,表示最多能拦截的导弹数。

 

样例输入

 

8
389 207 155 300 299 170 158 65

样例输出

 6
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[1001],dp[1001];//dp[i]表示以第i个导弹为末尾时最多可以拦截的数量 
 4 int n;
 5 int main()
 6 {
 7     while(cin>>n)
 8     {
 9         memset(dp,0,sizeof(dp));
10         for(int i=1;i<=n;i++)cin>>a[i],dp[i] = 1;
11         for(int i=1;i<=n;i++)
12         {
13             for(int j=1;j<i;j++)
14             {
15                 if(a[i]<=a[j])dp[i] = max(dp[i],dp[j]+1);
16             }
17         }
18         int ans = -1;
19         for(int i=1;i<=n;i++)ans = max(ans,dp[i]);
20         cout<<ans<<endl; 
21     }
22      return 0;
23 }

 

posted @ 2023-04-12 22:51  CRt0729  阅读(120)  评论(0)    收藏  举报