DP(DAG最长路)
题意:给出x轴上的线段的端点坐标,一个线段能覆盖另一个线段(端点不能相同),求出最多的线段覆盖并且从短到长给出路径。转化模型为DAG,求DAG上的最长路并且打印路径,用记忆化搜索实现
#include <cstdio> #include <cstring> #define N 550 int a[N],b[N],n; bool g[N][N]; int dp[N],path[N]; void dfs(int i) { if(dp[i]!=-1) return ; dp[i]=1; for(int j=1; j<=n; j++) if(g[i][j]) { dfs(j); if( dp[j]+1 > dp[i] ) { dp[i]=dp[j]+1; path[i]=j; } } return ; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); memset(g,0,sizeof(g)); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(a[i]<a[j] && b[j]<b[i]) //i能包含j g[i][j]=1; memset(dp,-1,sizeof(dp)); memset(path,-1,sizeof(path)); int max=0,m=0; for(int i=1; i<=n; i++) //枚举所有点求出最长路 { if(dp[i]==-1) { dp[i]=1; for(int j=1; j<=n; j++) if(g[i][j]) //i能包含j { dfs(j); if(dp[j]+1 > dp[i]) { dp[i]=dp[j]+1; path[i]=j; } } } if( dp[i]>max ) { max=dp[i]; m=i;} } int s[N],top=0; printf("%d\n",max); while(m!=-1) { s[top++]=m; m=path[m]; } for(int i=top-1; i>=0; i--) if(i) printf("%d ",s[i]); else printf("%d\n",s[i]); } return 0; }