动态规划 — 电线布设
题目描述
说实话,刚看到也是很懵逼,不相交子集是什么?乱七八糟的连线。
其实仔细想想后,觉得题目应该是说给定了这些点的连接端点,然后从他给的连线中选择出不想交的且条数最多的连线,如下面的例子便是其中的一个最大不相交子集。
终点数组 end[i] = {0,8,7,4,2,5,1,9,3,10,6};
解决思路,采用动态规划的方式
dp[ i ] [ j ] :表示到达端点i 时,最大不相交子集个数
i :表示 从 1 - N的起点
j :表示 终点
递推式:
当 i == 1时,
如果 j < end[1],当前最大不相交子集为空 dp[ 1 ] [ j ] = 0
如果 j >= end[1],当前最大不相交子集只有一条连线 dp[ 1 ] [ j ] = 1
当 i > 1时,
如果 j < end[i] ,表明当前端点连线还未加入集合 dp[ i ] [ j ] = dp [ i -1 ] [ j ]
如果 j >= end[i],判断当前连线能否加入最大不相交子集 dp [ i ] [ j ] = Math.max(dp [ i - 1 ] [ j ] , dp [i - 1] [ end[ i ] - 1] + 1 )
其实写到dp [ i ] [ j ] = dp [i - 1] [ j ] 还能理解,但是dp [ i ] [ j ] = Math.max(dp [ i - 1 ] [ j ] , dp [i - 1] [ end[ i ] - 1] + 1 ) 怎么去理解?
看这个最终填表图
比较的是左上角 与 从上一行继承下来的值, 与 dp [i - 1] [ end[ i ] - 1] + 1 比较是看 最大不相交集合中 有多少条线与 当前线不相交
填表过程
初始化
第二行
第三行
第四行
第五行
第六行
第七行
第八行
第九行
第十行
Java代码
public static void main(String[] args) {
//连线端点
int[] end = {
0,8,7,4,2,5,1,9,3,10,6