DAG上的动态规划

注意:这里的d(i)表示从节点i出发的最长路长度

d(i) = max{d(j)+1|(i,j)∈ E}, E 为边集

#include <stdio.h>
#include <limits.h>
#include <string.h>

#define MAXN 102

int u[MAXN], v[MAXN], w[MAXN][MAXN], d[MAXN];
int n;


int dp(int i){
    if(d[i] > 0) return d[i];
    d[i] = 1;
    int j;
    for(j=1; j<=n; j++){
        if(w[i][j]) d[i] = d[i] > dp(j)+1 ? d[i] : dp(j)+1;
    }
    return d[i];
}

void print(int i){
    printf("%d ", i);
    int j;
    for(j=1; j<=n; j++) if(w[i][j] && d[i] == d[j]+1){
        print(j);
        break;
    }
}

int main(){
    freopen("d:\\my.txt", "r", stdin);
    int i, j, ans=0, k;
    scanf("%d", &n);
    memset(w, 0, sizeof(w));
    for(i=1; i<=n; i++){
        scanf("%d %d", &u[i], &v[i]);
        if(u[i] > v[i]){
            u[i] += v[i];
            v[i] = u[i]-v[i];
            u[i] = u[i]-v[i];
        }
    }
    for(i=1; i<=n; i++){
        for(j=1; j<=n; j++){
            if(u[i]<u[j] && v[i]<v[j]) w[i][j] = 1;
        }
    }
    for(i=1; i<=n; i++) d[i] = dp(i);
    for(i=1; i<=n; i++){
        if(d[i] > ans) ans = d[k=i];
    }
    printf("%d\n", ans);
    print(k);


    return 0;
}

测试数据为

5
1 2
2 3
3 4
1 3
5 4

原文地址:https://www.cnblogs.com/tanhehe/p/2909189.html