題意:
給你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;
}