电路布线

                        电路布线

【问题描述】
在一块电路板的上、下两端分别有n个接线柱。根据电路设计,要求用导线(iπ(i))将上端接线柱i与下端接线柱π(i)相连,如图所示。

其中,π(i)1<=i<=n{12n}的一个排列。导线(iπ(i))称为该电路板上的第i条连线。对于任何1<=i π(j)

在制作电路板时,要求将这n条连线分布到若干绝缘层上。在同一层上的连线不相交。你的任务是要确定将哪些连线安排在第一层上,使得该层上有尽可能多的连线。换句话说,就是确定导线集Nets={ iπ(i)1<=i<=n}的最大不相交子集。

下面来举实例说明:

对于(1,8),不想交子集有(7,9)和(9,10),而相交子集为(2,7),(3,4),(4,2),(5,5)等。可以得出下面的结论

对于1<<i<<n,1<<j<<n,i<j并且π(i)<π(j),则满足这样的( i , π(i) )( j , π(j))构成了一个的不相交的子集

思路如下:

现在考虑第i次布线的情况:

a[i][j]上端接线柱i下端接线柱j前的最大不相交子集,则:

1. ( i, j)布线不满足相交子集的条件,则ij前的最大不相交子集等于ij - 1)布线(i - 1,j)布线的最大不相交子集的最大值,

a[i][j] = max(a[i][j - 1], a[i - 1][j])

2. ( i, j)布线满足相交子集的条件,则ij )前的最大不相交子集等于(i - 1,j - 1)的最大不想交子集加1,即a[i][j] = a[i - 1][j - 1] + 1

题目:

【输入形式】
输入文件第一行为整数n;第二行为用一个空格隔开的n个整数,表示π(i)

【输出形式】
输出文件第一行为最多的连线数m,第2行到第m+1行输出这m条连线(iπ(i))。

【输入样例】
10
1 8
2 7
3 4
4 2
5 5
6 1
7 9
8 3
9 10
10 6

【输出样例】
4

简单程序代码如下:

#include<stdio.h>    

 int max(int a, int b){  

    return a > b ? a : b;  

}  

  

int main(){  

   int n, i, j;  

    int a[100][100], b[100];  

    a[0][0] = 0;  

    scanf("%d", &n);  

    for(i = 0; i < n; ++i){  

        int j;  

       scanf("%d", &j);  

        scanf("%d", &b[j]);  

        a[i][0] = 0;  

        a[0][i] = 0;  

    }  

    for(i = 1; i <= n; ++i){  

        for(j = 1; j <= n; ++j){  

            if(b[i] == j){  

                a[i][j] = a[i - 1][j - 1] + 1;  

            }else{  

               a[i][j] = max(a[i - 1][j], a[i][j - 1]);  

           }  

        }  

    }  

    printf("%d\n", a[n][n]);  

   return 0;  

}  

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值