二刷动态规划,希望这遍加深对动态规划的理解,这道嵌套问题,可以转化为最长路,相当于为每个点找最行路,既然是最长路,就要按住一个点搜索到底,所以是DFS,然后找到第几个节点的长度最大,若有同样长度的节点,我们就用for+if(g[i][j] && d[i]==d[j]+1)的一个逆向思维来实现字典序.
Sample Input
8
14 9
15 19
18 12
9 10
19 17
15 9
2 13
13 10
Sample Output
4 8 3 2
#include<bits/stdc++.h>
#define maxn 101
using namespace std;
int a[maxn],b[maxn];
int g[maxn][maxn];
int d[maxn];
int n;
int dp(int i){
int& ans=d[i];
if(ans>0)
return ans;
ans=1;
for(int j=1;j<=n;j++ ){
if(g[i][j])
ans=max(ans,dp(j)+1);
}
return ans;
}
print_ans(int i){
printf("%d ",i);
for(int j=1;j<=n;j++)
if(g[i][j] && (d[i]==d[j]+1) )
{
print_ans(j);
break;
}
}
int main(){
scanf("%d",&n);
memset(d,-1,sizeof(d));
int i,j;
for(int i=1;i<=n;i++)
scanf("%d %d",&a[i],&b[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if((a[i]<a[j]&&b[i]<b[j]) || (a[i]<b[j]&& b[i]<a[j]))
g[i][j]=1;
}
for(int i=1;i<=n;i++) //把每个节点到其最远的点的距离算出来
if(d[i]==-1)
d[i]=dp(i);
int ans=0;
for(int i=1;i<=n;i++)
if(d[i]>d[ans])
ans=i;
print_ans(ans);
}