题意:
给你n个二元组(u,v),要你求最长的u是递增,v是递减的子序列。
思路:
这个题乍一看不就是个最长上升子序列吗?然后满足一个约束v是递减的求不就行了?
思路确实是这样,不过需要预处一下按u递增v递减排序(因为满足约束并且可以往回找),这样可以把所有的子序列全部找出来,如果不预处理是找不出来的,因为可能要往回找,不太好处理,所以预处理了,前提是子序列不连续的,并且是可以往回找的(只要满足条件,最长上升子序列是不可以往回找了,注意区别)连续就不行。然后就是最长子序列问题了,需要处理一下路径(没有处理好细节,浪费了很多时间)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
struct node{
int x,y,id;
node(){}
node(int a,int b):x(a),y(b){}
node(int a,int b,int c):x(a),y(b),id(c){}
};
struct node a[maxn];
int dp[maxn],path[maxn];
void dfs(int n){
if(n == 1)return;
else {
dfs(path[n]);
cout<<n<<endl;
}
}
bool cmp(node a,node b){
if(a.x == b.x)
return a.y > b.y;
return a.x < b.x;
}
int main(){
int cnt = 1;
while(scanf("%d%d",&a[cnt].x,&a[cnt].y)!=EOF){
a[cnt].id = cnt;
cnt ++;
}
cnt --;
dp[1] = 1;
sort(a+1,a+1+cnt,cmp);
for(int i = 1; i <= cnt; i++)path[i] = 1;
for(int i = 1; i <= cnt ; i++){
int M = 0 ;
for(int j = 1; j < i ; j++){
if(a[j].x < a[i].x && a[j].y > a[i].y)
if(dp[j] > M){M = dp[j];path[a[i].id] = a[j].id;}
}
dp[i] = M + 1;
}
int ans = 0;int sb = 0;
for(int i = 1; i <= cnt; i++){
if(dp[i] > ans){
ans = dp[i];sb = i;
}
}
//for(int i = 1; i <= cnt ; i++)cout<<path[i]<<' ';
cout<<ans<<endl;
dfs(a[sb].id);
}
所有解:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
struct node{
int x,y,id;
node(){}
node(int a,int b):x(a),y(b){}
node(int a,int b,int c):x(a),y(b),id(c){}
}a[maxn];
int dp[maxn],path[maxn],ans;
void dfs(int n,int dep){
if(n == 1)return;
else {
dfs(path[n],dep + 1);
cout<<n;
if(dep != 1)
cout<<" - > ";
}
}
bool cmp(node a,node b){
if(a.x == b.x)
return a.y > b.y;
return a.x < b.x;
}
int main(){
int cnt = 1;
while(scanf("%d%d",&a[cnt].x,&a[cnt].y)!=EOF){
a[cnt].id = cnt;
cnt ++;
}
cnt --;
dp[1] = 1;
sort(a+1,a+1+cnt,cmp);
for(int i = 1; i <= cnt; i++){
cout<<a[i].id<<" "<<a[i].x <<" "<<a[i].y<<endl;
}
for(int i = 1; i <= cnt; i++)path[i] = 1;
for(int i = 1; i <= cnt ; i++){
int M = 0 ;
for(int j = 1; j < i ; j++){
if(a[j].x < a[i].x && a[j].y > a[i].y)
if(dp[j] > M){M = dp[j];path[a[i].id] = a[j].id;}
}
dp[i] = M + 1;
}
int sb = 0;
vector<int>ve;
for(int i = 1; i <= cnt; i++){
if(dp[i] > ans){
ans = dp[i];sb = i;
}
}
ve.push_back(sb);
for(int i = 1; i <= cnt; i++){
if(ans == dp[i] && i != sb){
ve.push_back(i);
}
}
//for(int i = 1; i <= cnt ; i++)cout<<path[i]<<' ';
cout<<"lenth :"<<ans<<endl;
for(int i = 0; i < ve.size(); i++)
dfs(a[ve[i]].id,1),cout<<endl;
}