DAG上的动规嵌套矩形问题(含思考题)

OpenJudge - 1001:嵌套矩形问题
http://cdsdzx.openjudge.cn/practice/1001/

这是紫书里嵌套矩形问题的简化版

注意要将d数组初始化为0,如果初始化为1的话,在记忆化上会出错。

代码如下(核心代码来自紫书)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int N=1001;
int a[N],b[N],g[N][N],d[N],n,m,x,y,lans;
int dp(int i);
void print(int i);
int main()
{
    //freopen("in.txt","r",stdin);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>x>>y;
        g[x][y]=1;
    }
    memset(d,0,sizeof(d));//<<endl;  //这道题里起点是确定的 
    cout<<dp(1)-1<<" ";
    print(1);
    return 0;
}
int dp(int i)
{
    if(d[i]>0)
    return d[i];
    int& ans=d[i];
    ans=1;
    for(int j=1;j<=n;j++)
       if(g[i][j]>0)
          ans=max(ans,dp(j)+1);
    return ans;
}
void print(int i)
{
    cout<<i;
    for(int j=1;j<=n;j++)
      if(g[i][j]&&d[i]==d[j]+1)
      {
          cout<<"->";
          print(j);
          break;
      }
}

 对于紫书上提到的把d(i)改成表示以i为终点的最长路径长度;

我试了一下

int dp(int i)
{
if(d[i]>0)
return d[i];
int& ans=d[i];
ans=1;
for(int j=1;j<=n;j++)
if(g[j][i]>0)
ans=max(ans,dp(j)+1);
return ans;
}
void print(int i)
{
int k=0;
for(int j=1;j<=n;j++)
if(g[j][i]&&d[i]==d[j]+1)
{
k=1;
print(j);
break;
}
if(k) cout<<"->";
cout<<i;
}

粗看没有问题,还过了样例。但我想:假如有两条最长路 1->2->5->8,1->3->5->7,字典序最小的应是前者,但是根据d(i)最大并不容易找到字典序最短路的终点

原文地址:https://www.cnblogs.com/Neptune0/p/11755664.html