hdu1257 dp(最长上升子序列)

时间:2022-12-15 22:33:12

题意:有一种拦截系统,可以打击导弹,但是打击的高度会逐渐下降,因此为了防御导弹攻击,就必须用多个系统,现给出一列导弹依次的高度,求最少需要的系统数。

这道题是最长上升子序列问题,但是我一开始其实并没有想到,最开始我的思路是依次剔除最长下降子序列,每剔除一轮就是需要一个拦截系统,然后直到全部数都剔除了就可以知道要几个拦截系统了。而且这样做就是最长下降子序列符合 dp 的思路也可以自圆其说,所以说为什么我成长得这么慢,其实就是我刷 dp 专题就使劲往怎么用 dp 上想而不是怎么做出来上想,很多时候这样其实我的进步还是太小。

恩,这样做 WA 了,我也不是很清楚为什么 WA ,但是我在这么敲的时候就觉得这种思路其实很乱,就这么 A 了其实对我也不太好吧。

WA 了就知道要找新办法了,于是我想到了另一种做法,边遍历数字边建系统,对于一个数字,如果之前建立过的系统中有最小值大于这个数字的,那么就说明那个系统可以拦截这枚导弹,那么就把该拦截系统的最小值改为这个数字,而如果这个数字大于所有之前拦截系统的最小值的话,那就说明没有系统可以拦截这枚导弹了,我就重新建立一个系统,其最小值就是当前数字。其实我并不知道到底是不是对的,因为有一点需要考虑,当有很多系统都能拦截它时,我该优化哪一个呢,我选择了最小的,显然我也不知道这样对不对。然后我 A 了```不甘心地 A 了```

问过学长之后,学长告诉我,其实就只是一个最长上升子序列。细想一下,对于这个最长上升子序列而言,每一个数代表一个拦截系统的最小值,并且由于序列是上升的,每一个数都不能再拦截序列中的下一个数,因为下一个数更大,因此这个子序列的长度就是拦截系统数。我觉得这个说法我更能接受,或许之前那个做法只是因为数据弱所以就这么过了吧```

就这样,我感觉我和数据一样弱```

蠢,就是蠢!

hdu1257 dp(最长上升子序列)hdu1257 dp(最长上升子序列)
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 int dp[30001],a[30001];
 6 int main(){
 7     int n;
 8     while(scanf("%d",&n)!=EOF){
 9         int i,j,c=0;
10         memset(dp,0,sizeof(dp));
11         for(i=1;i<=n;i++){
12             scanf("%d",&a[i]);
13             int f=0;
14             for(j=1;j<=c;j++){
15                 if(a[i]<dp[j]){
16                     f=1;
17                     dp[j]=a[i];
18                     break;
19                 }
20             }
21             if(!f)dp[++c]=a[i];
22             sort(dp+1,dp+c+1);
23         }
24         printf("%d\n",c);
25     }
26     return 0;
27 }
View Code