FatMouse's Speed(DP+LIS變種)

在這裏插入圖片描述
在這裏插入圖片描述
題意:
給你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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章