标签:include while 语句 clu ace code 最小 span out
//这题的最大的重点就是思想 #include<bits/stdc++.h> using namespace std; #define int long long #define SYS system("pause"); const int N=1e5+100; int a[N],n,dp[N]; int32_t main(){ while(cin >> n){ for (int i = 1; i <= n;i++) cin >> a[i]; int ans = 0; for (int i = 1; i <= n;i++){ dp[i] = 1; for (int j = 1; j <= i;j++) if (a[j] < a[i]) dp[i] = max(dp[i], dp[j] + 1); ans = max(dp[i], ans); } cout << ans<<endl; } SYS return 0; }
这题的题意不是简单的递减序列破坏了 就ans++
一个例子:
20 15 10 16 14 5 6 4 3 2 1
如果是错误的思路,那么序列可以拆成:
20 15 10
16 14 5
6 4 3 2 1
但是其实,第一条序列的最小拦截高度是:10,大于第三条序列的最大高度:6
所以这个系统可以连着用
所以想到dp
然后这题的dp核心语句是:
1 for (int i = 1; i <= n;i++){ 2 dp[i] = 1; 3 for (int j = 1; j <= i;j++) 4 if (a[j] < a[i]) 5 dp[i] = max(dp[i], dp[j] + 1); 6 ans = max(dp[i], ans); 7 }
这是什么意思呢
首先
dp[i]=1;
这个是初始化的状态,不用管,
对于第一个导弹,dp[1]==1,意思是最少需要一座拦截系统
dp代表的是,对于总序列从第1个到第i个导弹,最少需要多少个拦截系统?
for(int j=1;j<=i;j++)
这个循环找的是哪一个导弹高度是小于第i个导弹的
对于例子来说
20 15 10 16 7 5 8 4 3 2 1
1 2 3 4 5 6 7 8 9 10 11
初始化dp[7]==1;第七个导弹,也就是高度为6的那个导弹
在前面的 20 15 10 16 14 5中,第5个导弹高度为7,是小于6的
所以dp[7]被更新为1+1==2;
第6个导弹的高度是5,是小于5的,但是并不会更新dp[7]
因为这一行:
dp[i]=max(dp[i],dp[j]+1);
并没有更新为3
最后的ans也就是2
标签:include while 语句 clu ace code 最小 span out
原文地址:https://www.cnblogs.com/guaguastandup/p/10409922.html