HDU5087 - Revenge of LIS II (次长上升子序列)
2014-11-02 13:53
274 查看
题目链接 HDU5087
【题意】求第二长的LIS的长度。
【分析】有两种方法;
1.直接添加一个dp[]在更新最大值的同时更新第二大值就可以了。
2.用cnt[]记录每个位置到达的次数,最终统计一遍最长长度出现的次数和,只出现一次的话次长序列就是最大序列-1,否则次长序列==最长序列
【AC CODE(1)】
【AC CODE(2)】
【题意】求第二长的LIS的长度。
【分析】有两种方法;
1.直接添加一个dp[]在更新最大值的同时更新第二大值就可以了。
2.用cnt[]记录每个位置到达的次数,最终统计一遍最长长度出现的次数和,只出现一次的话次长序列就是最大序列-1,否则次长序列==最长序列
【AC CODE(1)】
#include <cstdio> #include <cstring> #include <cmath> #include <map> #include <queue> #include <stack> #include <vector> #include <string> #include <algorithm> using namespace std; #define rep(i,a,n) for(int i = a; i < n; i++) #define repe(i,a,n) for(int i = a; i <= n; i++) #define per(i,n,a) for(int i = n; i >= a; i--) #define clc(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long LL; #define MAXN 1010 int a[MAXN], dp[MAXN][2], n;//dp[][0]表示最大值,dp[][1]是次大值 int sloved() { dp[0][0] = 1,dp[0][1] = 0; int fir = 1, sec = 0; for (int i = 1; i < n; i++) { dp[i][0] = 1, dp[i][1] = 0; for (int j = 0; j < i; j++) { if(a[j] >= a[i]) continue; if(dp[i][0] <= dp[j][0]+1)//当前>=最大值则更新最大和次大值 { dp[i][1] = max(dp[i][0], dp[j][1]+1);//次大值可能来自于原来次大值+1或者原来的最大值 dp[i][0] = dp[j][0]+1; } else if(dp[i][1] < dp[j][0]+1)//没有大于最大值,但可能大于次大值 dp[i][1] = dp[j][0]+1; } if(fir <= dp[i][0]) { sec = max(dp[i][1],fir); fir = dp[i][0]; } else if(sec < dp[i][0]) sec = dp[i][0]; } return sec; } int main() { #ifdef SHY freopen("e:\\1.txt", "r", stdin); #endif int t; scanf("%d%*c", &t); while(t--) { scanf("%d%*c", &n); rep(i,0,n) scanf("%d%*c", &a[i]); int s; printf("%d\n", sloved()); } return 0; }
【AC CODE(2)】
#include <cstdio> #include <cstring> #include <cmath> #include <map> #include <queue> #include <stack> #include <vector> #include <string> #include <algorithm> using namespace std; #define rep(i,a,n) for(int i = a; i < n; i++) #define repe(i,a,n) for(int i = a; i <= n; i++) #define per(i,n,a) for(int i = n; i >= a; i--) #define clc(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long LL; #define MAXN 1010 int a[MAXN], dp[MAXN], n, cnt[MAXN]; int sloved() { dp[0] = cnt[0] = 1; int ans = 1, s = 0; for (int i = 1; i < n; i++) { dp[i] = cnt[i] = 1; for (int j = 0; j < i; j++) { if(a[j] >= a[i]) continue; if(dp[i] < dp[j]+1) dp[i] = dp[j]+1, cnt[i] = cnt[j]; else if(dp[i] == dp[j]+1) cnt[i] += cnt[j]; } if(ans < dp[i]) ans = dp[i], s = i; } int sum = 0; rep(i,0,n) if(ans == dp[i]) sum += cnt[i]; if(1 == sum) ans--; return ans; } int main() { #ifdef SHY freopen("e:\\1.txt", "r", stdin); #endif int t; scanf("%d%*c", &t); while(t--) { scanf("%d%*c", &n); rep(i,0,n) scanf("%d%*c", &a[i]); printf("%d\n", sloved()); } return 0; }
相关文章推荐
- HDU 5087 Revenge of LIS II(次长上升子序列)
- HDU 5087 Revenge of LIS II(BestCoder Round #16)(次长上升子序列)
- HDOJ 5087 Revenge of LIS II (次大递增子序列)
- HDU5087 Revenge of LIS II (LIS变形)
- HDU 5087 Revenge of LIS II(次大递增子序列)
- HDU5087 Revenge of LIS II
- HDU5087 Revenge of LIS II (LIS变形)
- hdu5087 Revenge of LIS II (dp)
- hdu 5087 Revenge of LIS II
- POJ 1631 Bridging signals(LIS:最长上升子序列)
- HDU 1025 Constructing Roads In JGShining's Kingdom(DP,LIS最长上升子序列)
- 最长上升子序列(LIS)和最长下降子序列(LDS)
- LIS(最长上升子序列)
- hdu 5087 Revenge of LIS II(LIS,思路)
- 最长上升子序列LIS模板
- 动态规划-最长上升子序列(LIS)
- LIS求解最长上升子序列问题
- 【动态规划】最长上升子序列(LIS)
- LIS最长上升子序列O(n^2)&O(nlogn)
- HDU 1025 Constructing Roads In JGShining's Kingdom (简单dp, 最长上升子序列LIS)