电路布线问题

   制作电路板时,将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。

电路布线算法 java 电路布线算法实际问题_电路布线算法 java


  如果使得(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

电路布线算法 java 电路布线算法实际问题_电路布线问题_02

(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;

电路布线算法 java 电路布线算法实际问题_电路布线问题_03

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


电路布线算法 java 电路布线算法实际问题_电路布线算法 java_04



所以递推公式:

1)当i=1时

电路布线算法 java 电路布线算法实际问题_连线_05

(2)当i>1时

电路布线算法 java 电路布线算法实际问题_连线_06

#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[n][n]);
	return 0; 
}