电路布线问题

一:问题重述

在一块电路板上下两端分别有n个接线柱。根据电路设计,要求用导线(i,tail(i))将上端接线柱i与下端接线柱tail(i)相连,其中,tail(i),1<=i<=n{1,2,....,n}的一个排列。导线(i,tail(i))称为该电路板上的第i条连线。对于任何1<=i<j<=n,第i条连线和第j条连线相交的充分且必要条件是tail(i)>tail(j)。在制作电路板是,要求将这n条连线分布到若干绝缘层上,使得该层上有尽可能多的连线。换句话说,该问题就是确定导线集Nets={(i,tail(i)),1<=i<=n}的最大不相交集。。

二:最优子结构性质

N(i,j)={t|(t,tail(t))Nets,t<=i,tail(i)<=j},N(i,j)的最大不相交子集为MNS(i,j)Size(i,j)=|MNS(i,j)|

(1)i=1时,

如果j<tail(1),MNS(i,j)=N(1,j)=空集

如果j>=tail(1)MNS(i,j)=N(1,j)={(1,tail(1))}

(2)i>1时,

j<tail(i)。此时,(i,tail(i))N(i,j)。故再这种情况下,N(i,j)=N(i-1,j),从而Size(i,j)=Size(i-1,j)

j>=tail(i)

(i,tail(i))∈MNS(i,j),则对任何(t,tail(t))∈MNS(i,j)t<jtail(t)<tail(i)。否则,(t,tail(t))(i,tail(i))相交。

(i,tail(i))∉MNS(i,j),则对任何(t,tail(t))∈MNS(i,j),有t<i。从而MNS(i,j)⊆N(i-1,j)。因此Size(i,j)<=Size(i-1,j)。另一方面MNS(i-1,j)⊆N(i,j),故又有Size(i,j)>=Size(i-1,j),从而Size(i,j)=Size(i-1,j)

综上可知。电路布线问题满足最优子结构。。

三:递归表达式:

(1)i=1

j<tail(1), Size(i,j)=0;

j>=tail(1),Size(i,j)=1;

(2)i>1

j<tail(1),Size(i,j)=Size(i-1,j)

j>=tail(1),Size(i,j)=max{Size(i-1,j),Size(i-1,tail(i)-1)+1}

四:代码如下:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int tail[100];//记录下方与坐标相连的点
int size[100][100];//从上方i点到下方j点之间最大不相交集合
int nets[100];//记录最大不相交集合
void init(int n)
{
    for(int i=1;i<=n;i++)
    {
        cin>>tail[i];
    }
}
void MNS(int n)
{
    for(int i=1;i<tail[1];i++)
    {
        size[1][i]=0;
    }
    for(int i=tail[1];i<=n;i++)
    {
        size[1][i]=1;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<tail[i];j++)
        {
            size[i][j]=size[i-1][j];
        }
        for(int j=tail[i];j<=n;j++)
        {
            size[i][j]=max(size[i-1][j],size[i-1][tail[i]-1]+1);
        }
    }
}
int  traceback(int n)
{
    int j=n;
    int m=0;
    for(int i=n;i>1;i--)
    {
        if(size[i][j]!=size[i-1][j])
        {
            nets[++m]=i;j=tail[i]-1;
        }
    }
    if(j>=tail[1])nets[++m]=1;
    return m;
}
void out(int m)
{
    for(int i=m;i>=1;i--)
    {
        cout<<nets[i]<<" ";
    }
    cout<<endl;
}
int main()
{
    int n;
    cin>>n;
    init(n);
    MNS(n);
    int m=traceback(n);
    out(m);
    return 0;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值