hdu1257 dp(最長上升子序列)


題意:有一種攔截系統,可以打擊導彈,但是打擊的高度會逐漸下降,因此為了防御導彈攻擊,就必須用多個系統,現給出一列導彈依次的高度,求最少需要的系統數。

這道題是最長上升子序列問題,但是我一開始其實並沒有想到,最開始我的思路是依次剔除最長下降子序列,每剔除一輪就是需要一個攔截系統,然后直到全部數都剔除了就可以知道要幾個攔截系統了。而且這樣做就是最長下降子序列符合 dp 的思路也可以自圓其說,所以說為什么我成長得這么慢,其實就是我刷 dp 專題就使勁往怎么用 dp 上想而不是怎么做出來上想,很多時候這樣其實我的進步還是太小。

恩,這樣做 WA 了,我也不是很清楚為什么 WA ,但是我在這么敲的時候就覺得這種思路其實很亂,就這么 A 了其實對我也不太好吧。

WA 了就知道要找新辦法了,於是我想到了另一種做法,邊遍歷數字邊建系統,對於一個數字,如果之前建立過的系統中有最小值大於這個數字的,那么就說明那個系統可以攔截這枚導彈,那么就把該攔截系統的最小值改為這個數字,而如果這個數字大於所有之前攔截系統的最小值的話,那就說明沒有系統可以攔截這枚導彈了,我就重新建立一個系統,其最小值就是當前數字。其實我並不知道到底是不是對的,因為有一點需要考慮,當有很多系統都能攔截它時,我該優化哪一個呢,我選擇了最小的,顯然我也不知道這樣對不對。然后我 A 了```不甘心地 A 了```

問過學長之后,學長告訴我,其實就只是一個最長上升子序列。細想一下,對於這個最長上升子序列而言,每一個數代表一個攔截系統的最小值,並且由於序列是上升的,每一個數都不能再攔截序列中的下一個數,因為下一個數更大,因此這個子序列的長度就是攔截系統數。我覺得這個說法我更能接受,或許之前那個做法只是因為數據弱所以就這么過了吧```

就這樣,我感覺我和數據一樣弱```

蠢,就是蠢!

 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM