最多不相交线段

题目描述:已知数轴上0<N<10000条线段。每条线段按照端点Ai和Bi(Ai<>Bi,i=1..N)定义。端点坐标在(-999,999)内,坐标为整数。有些线段可能相交。编程实现删除最少数目的线段,使得余下的任意两条线段不相交。输入:第一行为一整数N。接下来有N行,每行包含两个整数 (Ai 和 Bi), 用空格隔开。
输出:整数p,即删除后余下的线段数。
样例输入:
3
6 3
1 3
2 5

样例输出:2

代码:

#include<stdio.h>
typedef struct _line
{
  int x;
  int y;
}Line;
int cmp(const void* a, const void* b)
{
  Line* l1 = (Line*)a;
  Line* l2 = (Line*)b;
  return l1->y - l2->y;
}
int main()
{
  Line a[10000];
  int n;
  scanf("%d", &n);
  int i;
  for(i = 0; i < n; i++)
  {
    int x, y;
    scanf("%d%d", &x, &y);
    if(x <= y)
    {
      a[i].x = x; a[i].y = y;
    }
    else
    {
      a[i].y = x; a[i].x = y;
    }
  }
  qsort(a, n, sizeof(a[0]), cmp);
  int count = 0, j;
  for(i = 0; i < n; )
  {
    count++;
    for(j = i + 1; j < n; j++)
    {
      if(a[j].x >= a[i].y) break;
    }
    i = j;
  }
  printf("%d\n", count);
}
要解决交叉匹配问题,首先需要理解动态规划的基本原理。动态规划通过将问题分解为子问题,并使用已解决的子问题的解来构建最终解,可以有效地提高计算效率。在交叉匹配问题中,我们需要计算两行最多量的匹配线段,每条a匹配线段恰好与一条b匹配线段相交,且a和b不能相同,也不允许两条线段从同一个出发。 参考资源链接:[动态规划解决交叉匹配问题](https://wenku.youkuaiyun.com/doc/3gtiaxz93p?spm=1055.2569.3001.10343) 具体来说,我们可以定义一个二维组dp[i][j],其中i和j分别表示第一行和第二行考虑的的位置。dp[i][j]的值表示到达当前位置i和j时,能够形成的最大匹配线段量。状态转移方程如下所示: 如果第一行的i等于第二行的j,且i和j之前没有被匹配过,那么dp[i][j] = dp[i-1][j-1] + 1; 否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1]),即不考虑当前对的匹配。 初始化条件是dp[0][0] = 0,因为开始时还没有考虑任何对。 在C++中,我们可以使用一个二维组来存储dp值,并通过嵌套循环遍历所有的对来填充这个组。最终dp组的最后一个元素dp[n][m](其中n和m分别表示两行的长度)即为所求的最多匹配线段量。 示例代码如下:(代码略) 在实现上述算法时,需要特别注意对匹配的条件,确保不会违反规则导致重复计算。通过这种方式,我们可以在C++中高效地解决交叉匹配问题,计算出两行最多量的匹配线段。 进一步深入学习动态规划以及它在解决最优化问题中的应用,可以参考《动态规划解决交叉匹配问题》,这本资源将为你提供交叉匹配问题的详细解释以及动态规划算法的更深入理解,帮助你在信息学竞赛和实际工作中更好地应用这一强大工具。 参考资源链接:[动态规划解决交叉匹配问题](https://wenku.youkuaiyun.com/doc/3gtiaxz93p?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值