题目
在电路板的上、下两端分别有n个接线柱。根据电路设计,用导线(i,π(i))将上端接线柱与下端接线柱相连,要求找到导线的最大不相交子集
示例
输入: 下端接线柱取值 [8,7,4,2,5,1,9,3,10,6]
输出: 最大不相交连线分别为:
3 4
5 5
7 9
9 10
最大不相交连线数目为:4
解题思路
1.当i=1时,j<n(i)。代表的是与第一个点相连的前无效边,那么他们的size就是0,因为size是:第一层内不相交的有效边的最多个数
2.当i=1时,j>=n(i)。当j=n(i)的时候,代表N(i,j)就是有效边了,此时是第一条有效边,不用顾虑其他,将这条边加入到第一层中,也就是size=1;当j>n(i)的时候,代表N(i,j)为后无效边,他的影响不了size的大小,所以size还是1。
3.当i>1时,j<n(i)的时候,代表着是与第i个点相连的前无效边,此时的N(i,j)的size依赖于N(i-1,j)的size,我们用反证法来证明:
如果size(i,j)!=size(i-1,j),那么就有size(i,j)>size(i-1,j)或者size(i,j)<size(i-1,j)
size(i,j)>size(i-1,j),当我们要让size(i,j)>size(i-1,j)的时候,代表着我们要有一条新的有效边加入,但是题目中j<n(i),此时的边都为无效边,没有有效边,与条件不符。
size(i,j)<size(i-1,j),这个显然不可能,没加边就不错了,还能减边?
4.当i>1时,j>=n(i)的时候。当j=n(i)的时候,也就是N(i,j)为有效边时,我们考虑两方面:1.这个有效边可以放进第一层2.这个有效边不可以放进第一层。
(1).这个有效边可以放进第一层的话,那么此时的size=size[i-1,n(i)-1]+1)了。
(2).不可以可以放进第一层的话,那么此时的size=size[i-1,j]了。

import java.util.ArrayList;
import java.util.Scanner;
public class DianLu {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner s = new Scanner(System.in);
String s1=s.nextLine();
String[]s2=s1.split(",");
int[]a=new int[s2.length];
for(int i=0;i<s2.length;i++){
a[i]=Integer.parseInt(s2[i]);
}
int n=a.length;
int[][]size=new int[n+1][n+1];
for(int j=0;j<a[0];j++) size[1][j]=0;
for(int j=a[1];j<=n;j++) size[1][j]=1;
for(int i=2;i<n;i++){
for(int j=0;j<a[i-1];j++) size[i][j]=size[i-1][j];
for(int j=a[i-1];j<=n;j++) size[i][j]=Math.max(size[i-1][j], size[i-1][a[i-1]-1]+1);
}
size[n][n]=Math.max(size[n-1][n], size[n-1][a[n-1]-1]+1);
int j=n;
ArrayList<Integer>net = new ArrayList<Integer>();
for(int i=n;i>1;i--){
if(size[i][j]!=size[i-1][j]){
net.add(i);
j=a[i-1]-1;
}
}
if(j>=a[0])//处理i=1的情形
{
net.add(1);
}
int num=net.size();
System.out.println("最大不相交连线分别为:");
for(int i=net.size()-1;i>=0;i--){
int c=net.get(i);
System.out.println(c+" "+a[c-1]);
}
System.out.println("最大不相交连线数目为:"+num);
}
}
该博客介绍了如何解决电路板上寻找最大不相交连线的问题,给出了详细的解题思路和代码实现。通过动态规划方法,确定了每一步的最大不相交连线数,并最终得到最大不相交连线的集合。此问题涉及到图论和算法优化,对于理解动态规划和电路设计有很好的启示作用。
3495

被折叠的 条评论
为什么被折叠?



