您的位置:首页 > 其它

电路布线问题

2017-01-01 20:31 190 查看
电路布线问题

   制作电路板时,将n条连线分布到若干绝缘层上。在同一层的连线不相交。电路布线问题就是要确定将哪些连线安排到第一层上,使该层上有尽可能多的连线。

  输入一个整数n代表接线柱的数量,输入n个数代表与上接线柱连接的下接线柱编号

样例输入

10

8 7 4 2 5 1 9 3 10 6

样例输出

4

解:

例如,给定如图的电路板。从10条连线中,选取不相交的最大连线集合。用a(i)=j表示要求上排的第i个接线柱要求接到下排的第 j 个接线柱。

  在图中,a(1)=8 , a(2)=7, a(1)=4, a(1)=2, a(1)=5, a(1)=1, a(1)=9, a(1)=3, a(1)=10, a(1)=6。



  如果使得(i , a[i])与(j , a[j])不相交,假设 j>I 则两条线不相交的充分必要条件为 a[j]>a[i]。在制作电路板时,要求将这n条连线分布到若干绝缘层上。在同一层上的连线不相交。电路布线问题要确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。换句话说,该问题要求确定所有导线集的最大不相交子集。

  记N(i,j){(t,a(t)) |  t<=i,a(t)<=j }代表上接线柱小于等于i并且下接线柱小于等于j的连线的集合。N(i,j)的最大不相交子集为MNS(i,j),假设MNS(i,j)中的连线数目为dp[i][j];

下面对MNS(i,j)进行判断区分:

(1) 当i = 1时

①如果j>=a[i],为了考虑更多的连线,则(i,a[i])应当在集合MNS(i,j) 中,即dp(i,j)=1;

②如果j<a[i],此时则(i,a[i])不应放在集合MNS(i,j) 中,即dp(i,j)=0



(2)当i >1时

①j<a(i)。

此时,(i,a(i))不属于MNS(i,j)。故在这时,MNS(i,j)
=MNS(i-1,j),从而dp(i,j)=dp(i-1,j)。

②j >=a(i)。

  若(i, a(i))∈MNS(i,j),则对任意(t, a(t))∈MNS(i,j)有t
<i且a(t)<a(i);否则,(t,a(t))与(i,a(i))相交。在这种情况下MNS(i,j)-{(i,a(i))}是N(i-1,a(i)-1)的最大不相交子集。否则,子集MNS(i-1,a(i)-1)∪{(i,a(i))}包含于N(i,j)是比MNS(i,j)更大的N(i,j)的不相交子集。这与MNS(i,j)的定义相矛盾。

  若(i, a(i))不属于MNS(i,j),则对任意(t,
a(t))∈MNS(i,j),有t<i。从而MNS(i,j)包含于N(i-1,j),因此,dp(i,j)≤dp(i-1,j)。另一方面,MNS(i-1,j)包含于N(i,j),故又有dp(i,j)≥dp(i-1,j),从而Size(i,j)=Size(i-1,j)。

(i,a[i])属于MNS(i,j),则dp(i,j)=dp(i-1,a[i])+1;



(i,a[i])不属于MNS(i,j),则dp(i,j)=dp(i-1,j);



所以递推公式:

1)当i=1时


(2)当i>1时


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

#define MAX(a, b) ((a)>(b)?(a):(b))

int main()
{
int n;
int a[100],dp[100][100];
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
for(int j=1;j<=n;j++)
{
if(j<a[1])
dp[1][j]=0;
else
dp[1][j]=1;
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j<a[i])
dp[i][j]=dp[i-1][j];
else
dp[i][j]=MAX(dp[i-1][j],dp[i-1][a[i]-1]+1);
}
}

printf("%d\n",dp

);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息