算法-电路布线(动态规划)

该博客介绍了如何解决电路板上寻找最大不相交连线的问题,给出了详细的解题思路和代码实现。通过动态规划方法,确定了每一步的最大不相交连线数,并最终得到最大不相交连线的集合。此问题涉及到图论和算法优化,对于理解动态规划和电路设计有很好的启示作用。

题目
在电路板的上、下两端分别有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);
	}

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值