最长上升子序列LIS集合 POJ2533,POJ1631,POJ1887,POJ1609
2014-02-10 20:32
337 查看
POJ2533 赤裸裸的求最长上升子序列,复杂度为n^2的模版
POJ1631,同样是赤裸裸的LIS,复杂度为nlogn的模版,n^2铁定超时
POJ1887,最长不上升子序列,反过来做即可,注意输出格式,前导有个空格,后导两个案例之间有个空行,而且不会提醒PE 只会说WA
POJ1609,最长不下降子序列,不过是有两个限制条件,先进行排序满足其中一条,再在这个基础上进行 LIS算法即,可注意不等号要改变,还有题目问的是最多,而序列不是给定的,所以自己要先进行排序
还有另一种做法,因为范围还是比较小的,所以可以直接dp做
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define eps 1e-7
#define inf 0xfffffff
//const ll INF = 1ll<<61;
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;
//#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin)
//#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout)
int num[112][112],dp[112][112];
void clear() {
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
}
int main() {
int n;
while(scanf("%d",&n),n) {
clear();
int x,y;
for(int i=1;i<=n;i++) {
scanf("%d %d",&x,&y);
num[x][y]++;
}
for(int i=1;i<=100;i++)
for(int j=1;j<=100;j++)
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + num[i][j];
printf("%d\n",dp[100][100]);
}
puts("*");
return EXIT_SUCCESS;
}
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff //const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; //#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin) //#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout) int dp[10000 + 5]; int num[10000 + 5]; void clear() { memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); } int main() { int n; while(cin>>n) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) cin>>num[i]; int ans = 1; for(int i=1;i<=n;i++) dp[i] = 1; for(int i=2;i<=n;i++) { int m = 0; for(int j=1;j<i;j++) { if(num[i] > num[j] && dp[j] + 1 > dp[i]) { dp[i] = dp[j] + 1; } if(ans < dp[i]) ans = dp[i]; } } cout<<ans<<endl; } return EXIT_SUCCESS; }
POJ1631,同样是赤裸裸的LIS,复杂度为nlogn的模版,n^2铁定超时
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff //const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; //#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin) //#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout) int dp[100000 + 5]; int num[100000 + 5]; void clear() { memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); } int main() { int t,n; cin>>t; while(t--) { clear(); cin>>n; for(int i=1;i<=n;i++) cin>>num[i]; int ans = 0; for(int i=1;i<=n;i++) { int tmp = num[i]; int left = 1; int right = ans; while(left <= right) { int mid = (left + right)/2; if(dp[mid] < tmp) left = mid + 1; else right = mid -1; } dp[left] = tmp; if(ans < left) ans++; } cout<<ans<<endl; } return EXIT_SUCCESS; }
POJ1887,最长不上升子序列,反过来做即可,注意输出格式,前导有个空格,后导两个案例之间有个空行,而且不会提醒PE 只会说WA
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff //const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; //#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin) //#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout) int dp[100000 + 5]; int num[100000 + 5]; void clear() { memset(dp,0,sizeof(dp));/* memset(num,0,sizeof(num));*/ } int main() { int a; int Case = 0; clear(); while(scanf("%d",&a)) { clear(); int n = 1; if(a == -1)break; num = a; while(true) { scanf("%d",&a); if(a == -1)break; num[++n] = a; } for(int i=1;i<=n;i++) dp[i] = 1; int ans = 1; for(int i=n-1;i>=1;i--) { for(int j=i+1;j<=n;j++) { if(dp[j] + 1 > dp[i] && num[i] > num[j]) dp[i] = dp[j] + 1; if(dp[i] > ans) ans = dp[i]; } } printf("Test #%d:\n",++Case); printf(" maximum possible interceptions: %d\n\n",ans); } return EXIT_SUCCESS; }
POJ1609,最长不下降子序列,不过是有两个限制条件,先进行排序满足其中一条,再在这个基础上进行 LIS算法即,可注意不等号要改变,还有题目问的是最多,而序列不是给定的,所以自己要先进行排序
#include<iostream> #include<cstdio> #include<list> #include<algorithm> #include<cstring> #include<string> #include<queue> #include<stack> #include<map> #include<vector> #include<cmath> #include<memory.h> #include<set> #define ll long long #define eps 1e-7 #define inf 0xfffffff //const ll INF = 1ll<<61; using namespace std; //vector<pair<int,int> > G; //typedef pair<int,int > P; //vector<pair<int,int> > ::iterator iter; // //map<ll,int >mp; //map<ll,int >::iterator p; //#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin) //#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout) int dp[100000 + 5]; struct Node { int x,y; }node[100000 + 5]; void clear() { memset(dp,0,sizeof(dp)); memset(node,0,sizeof(node)); } bool cmp(Node x,Node y) { if(x.x == y.x) return x.y < y.y; return x.x <y.x; } int main() { int n; while(scanf("%d",&n) == 1) { if(n == 0) { puts("*"); break; } clear(); for(int i=1;i<=n;i++) scanf("%d %d",&node[i].x,&node[i].y); sort(node+1,node+n,cmp); for(int i=1;i<=n;i++) dp[i] = 1; int ans = 1; for(int i=2;i<=n;i++) { for(int j=1;j<i;j++) { if(dp[j] + 1 > dp[i] && node[i].x >= node[j].x && node[i].y >= node[j].y) dp[i] = dp[j] + 1; if(dp[i] > ans) ans = dp[i]; } } printf("%d\n",ans); } return EXIT_SUCCESS; }
还有另一种做法,因为范围还是比较小的,所以可以直接dp做
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define eps 1e-7
#define inf 0xfffffff
//const ll INF = 1ll<<61;
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;
//#define IN freopen("c:\\Users\\linzuojun\\desktop\\input.txt", "r", stdin)
//#define OUT freopen("c:\\Users\\linzuojun\\desktop\\output.txt", "w", stdout)
int num[112][112],dp[112][112];
void clear() {
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
}
int main() {
int n;
while(scanf("%d",&n),n) {
clear();
int x,y;
for(int i=1;i<=n;i++) {
scanf("%d %d",&x,&y);
num[x][y]++;
}
for(int i=1;i<=100;i++)
for(int j=1;j<=100;j++)
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + num[i][j];
printf("%d\n",dp[100][100]);
}
puts("*");
return EXIT_SUCCESS;
}
相关文章推荐
- 【POJ2533】Longest Ordered Subsequence(LIS-最长上升子序列/DP)
- LIS最长上升子序列(打印路径)
- 动态规划-最长上升子序列LIS
- ACM模板——最长上升子序列(LIS)
- Hdu5748-Bellovin-最长上升子序列(LIS)
- SDUSTOJ 1801 LIS2(最长上升子序列不同值的数量)
- 动态规划之最长上升子序列(LIS模板)再整理
- LIS 最长严格上升子序列问题
- CodeForces - 846A Curriculum Vitae LIS(最长上升子序列)n logn
- 动态规划-最长上升子序列(LIS)
- 最长上升子序列LIS
- 【动态规划】最长上升子序列(LIS)
- 最长上升子序列问题 (LIS)
- <OJ_Sicily>LIS最长上升子序列
- POJ 2533 Longest Ordered Subsequence(LIS:最长上升子序列)
- [动态规划]之裸lis之最长上升子序列POJ 2533
- UVALive2931 POJ1631 HDU1950 ZOJ1986 Bridging signals【最长上升子序列+二分+堆栈】
- uvaoj 10534 Wavio Sequence 最长上升子序列(LIS)
- 动态规划 LIS最长上升子序列
- 最长上升子序列LIS