ABCDE,五个人,已按顺序排好,现在重新排队,要求每个人都不排到原来的位置上,问有多少种排法?...

本文深入探讨了排列组合问题中的一种特殊场景:当N个人重新排队,且每个人都不能站在原来的位置时,有多少种排法。通过递归公式f(n)=n!-C(n,1)*f(n-1)-...-C(n,k)*f(n-k)-...-C(n,n-2)*f(2)-1,详细解析了如何计算这种无重复排列的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1 package acknowledge;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  * ABCDE,五个人,已按顺序排好,现在重新排队,要求每个人都不排到原来的位置上,问有多少种排法
 7  * 
 8  * @author HHY 扩展:有N个人排队,现在重新排队,每个人都不排到原来的位置上,问有多少中排法? 
 9  * 用 f(n) 表示n个人有多少种排法 理解思路:
10  *     1. 已知f(1) = 0, f(2) = 1 
11  *     2. n = 3 时,不做限制有 3! 种排法 
12  *         1个人站在原位,有 C(3,1) * f(2) 种排法
13  *         2个人站在原位,有 1 种排法 则 f(3) = 3! - C(3,1)*f(2) - 1 
14  *     3. n = 4时,不做限制有 4! 种排法 
15  *         1个人站在原位,有 C(4,1) * f(3) 种排法 
16  *         2个人站在原位,有 C(4,2) * f(2)种排法 
17  *         3个人站在原位,有 1 种排法 
18  *         则 f(4) = 4! - C(4,1) * f(3) - C(4,2) * f(2) - 1
19  *     4. n = k 时,不做限制有 k! 种排法 1个人站在原位,有 C(k,1) * f(k-1) 种排法 
20  *            2个人站在原位,有 C(k,2) * f(k-2) 种排法 
21  *            。。。 
22  *         k-1个人站在原位,有 1 种排法 
23  *         则 f(k) = k! - C(k,1) * f(k-1) - ... - C(k, k-2) * f(2) -1
24  */
25 public class GetNoRepeatSort {
26 
27     /**
28      * 求n的阶乘
29      * 
30      * @param n
31      * @return
32      */
33     public static int getMultiN(int n) {
34         int k = n;
35         for (int i = n - 1; i > 0; i--) {
36             k *= i;
37         }
38         return k;
39     }
40 
41     /**
42      * 求C(n,k) = n! / k!(n-k)!
43      * 
44      * @param n
45      * @param k
46      * @return
47      */
48     public static int getC(int n, int k) {
49         int mulN = getMultiN(n);
50         int mulk = getMultiN(k);
51         int mul = getMultiN(n - k);
52         return mulN / (mulk * mul);
53     }
54 
55     /**
56      * f(n) = n! - C(n,1) * f(n-1) - ... - C(n,k) * f(n-k) - ... - C(n,n-2)*f(2) - 1
57      * 
58      * @param n
59      * @return
60      */
61     public static int getSortNum(int n) {
62         if (n <= 1)
63             return 0;
64         if (n == 2)
65             return 1;
66         int sub = 1;
67         for (int k = 1; k <= n-2; k++) {
68             sub += getC(n, k) * getSortNum(n - k);
69         }
70         return getMultiN(n) - sub;
71     }
72 
73     public static void main(String[] args) {
74         System.out.println("Input a integer:");
75         Scanner sc = new Scanner(System.in);
76 
77         int n = sc.nextInt();
78         System.out.println("SortNum: " + getSortNum(n));
79     }
80 }

 

转载于:https://www.cnblogs.com/huanghy/p/10533862.html

<think>我们正在讨论CIDR(无类别域间路由)如何比传统的ABCDE类IP分类提供更多地址,以及每个路由器是否可以分配一个网络号。 首先,回顾传统IP分类(ABCDE类): - A类:网络号占8位(首位固定为0),范围1.0.0.0到126.255.255.255,可容纳126个网络(每个网络约1677万台主机) - B类:网络号占16位(前两位固定为10),范围128.0.0.0到191.255.255.255,可容纳16384个网络(每个网络约65534台主机) - C类:网络号占24位(前三位固定为110),范围192.0.0.0到223.255.255.255,可容纳约209万个网络(每个网络254台主机) - D类(组播)和E类(保留)用于普通主机。 传统分类的缺点: 1. 地址分配灵活:导致大量地址浪费。例如,一个组织需要2000个地址,分配一个B类地址(65534个地址)会浪费6万多个地址;而分配8个C类地址(8*254=2032)又会导致路由表过大(因为每个C类网络在路由表中占一项)。 2. 路由表爆炸:随着网络数量增加,路由表变得过大。 CIDR的引入解决了这些题: 1. 消除传统分类:CIDR使用“网络前缀”的概念,再有A、B、C类的固定划分。IP地址表示为:<网络前缀><主机号>,其中网络前缀长度可变(用“斜线记法”表示,如192.168.0.0/24)。 2. 路由聚合(超网):CIDR允许将多个连续的IP地址块聚合成一个更大的地址块(超网),从而减少路由表项。例如,一个ISP可以分配一个地址块(如192.24.0.0/15),然后将其划分为更小的块分配给同组织,而互联网上的路由器只需要知道这个大的地址块(/15)即可,内部再由ISP路由器进行更具体的转发。 1:CIDR如何提供更多地址? 注意:CIDR本身并没有增加IP地址的总数(IPv4地址总数仍是2^32个),而是通过更高效的地址分配和路由聚合,减少了地址浪费,从而让可用地址得到更充分的利用。所以,CIDR并没有“创造”更多地址,而是让地址分配更灵活,减少浪费,从而在效果上相当于提供了更多可用的地址。 具体机制: - 灵活分配:根据用户需求分配适当大小的地址块。例如,一个需要2000个地址的组织,可以分配一个/21的地址块(2048个地址),而是像传统分类那样只能分配一个B类(浪费6万多个)或多个C类(导致路由表膨胀)。 - 减少浪费:避免了传统分类中大量的地址浪费(如B类网络分配给小型组织)。 题2:每个路由器是否可以分配一个网络号? 这里需要澄清概念: - 网络号(或网络前缀)是分配给一个网络的,而是分配给路由器的。一个路由器通常连接多个网络(每个接口连接一个网络),因此一个路由器会有多个IP地址(每个接口一个,属于同的网络)。 - 在CIDR中,一个网络(可以是一个物理网络,如以太网)会被分配一个网络前缀(即一个CIDR地址块)。例如,一个局域网可能被分配192.168.1.0/24,那么这个网络上的所有主机(包括连接这个网络的路由器接口)的IP地址都在这个地址块内。 - 路由器本身占用整个网络号,但它的每个接口都需要一个IP地址(通常是该网络中的某个地址,比如网络中的第一个可用地址)。 所以,严格来说,是给路由器分配一个网络号,而是给路由器所连接的每个网络分配一个网络前缀(即CIDR块)。路由器通过它的多个接口连接多个网络,因此它会有多个网络前缀。 总结: 1. CIDR通过灵活的地址分配(任意长度的网络前缀)和路由聚合,提高了IP地址的利用率,减少了浪费,从而在效果上提供了更多可用地址。 2. 路由器并被分配一个网络号,而是它的每个接口都位于一个网络中,该网络有一个CIDR网络前缀。 引用说明: 根据提供的引用: [^1] 解释了CIDR的基本概念,包括超网。 [^2] 提到CIDR由网络前缀和主机号组成。 [^3] 说明CIDR打破了A/B/C类的限制,采用“IP地址/前缀长度”的方式。 因此,我们在回答中会引用这些内容。 在,我们按照要求组织答案: 1. 使用中文回答。 2. 数学表达式使用$...$(行内)或$$...$$(独立)。 3. 在引用的地方添加引用标记。 4. 生成相关题。</think>### CIDR 如何提供更多 IP 地址? CIDR(无类别域间路由)通过**打破传统 IP 地址分类的刚性结构**,显著提高 IP 地址的利用率: 1. **消除固定类别限制** - 传统 ABCDE 类划分: - A 类:固定 `/8` 前缀(如 `10.0.0.0/8`) - B 类:固定 `/16` 前缀(如 `172.16.0.0/16`) - C 类:固定 `/24` 前缀(如 `192.168.1.0/24`) - **CIDR 创新**: 允许**任意长度的网络前缀**(如 `/12`, `/20`, `/27`),再受限于 `/8`、`/16`、`/24` 的固定划分[^2][^3]。 2. **地址分配更精细** - 例:一个组织需 2000 个 IP 地址: - 传统方案:分配一个 B 类网段(`/16`,共 $2^{16}-2=65534$ 地址),**浪费 98% 地址**。 - CIDR 方案:分配 `/21` 网段($2^{11}-2=2046$ 地址),**利用率 >97%**[^3]。 - 数学原理:可用地址数 = $2^{(32-n)}-2$($n$ 为前缀长度)[^2]。 3. **路由聚合(超网)** - 将多个连续小网段合并为一个大网段(超网),减少路由表条目: ```markdown 原路由表:192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24 CIDR 聚合:192.168.0.0/22 (覆盖 192.168.0.0~192.168.3.255) ``` - **效果**:路由器只需存储 1 条聚合路由,而非 4 条独立路由[^1][^3]。 4. **缓解地址枯竭** - 通过灵活分配和路由聚合,CIDR 使 IPv4 地址空间的利用率从传统分类的 **<50%** 提升至 **>90%**[^3]。 --- ### 每个路由器能否分配一个网络号? **完全正确**,需分场景理解: 1. **路由器接口分配网络号** - 每个路由器接口连接一个物理网络,因此**每个接口需配置一个网络号**(CIDR 块)。 - 例:路由器连接两个子网: - 接口 1:`192.168.1.1/24` → 网络号 `192.168.1.0/24` - 接口 2:`10.2.0.1/16` → 网络号 `10.2.0.0/16` 2. **路由器自身独占网络号** - 路由器作为**网络边界设备**,其接口地址属于所连子网的 CIDR 块,而非独占整个网络号。 - 关键区别: - **终端设备**:分配主机 IP(如 `192.168.1.100/24`) - **路由器接口**:分配网关 IP(如 `192.168.1.1/24`),共享同一网络号[^4]。 3. **特殊场景:路由器管理地址** - 部分企业级路由器支虚拟管理接口(如 `Loopback0`),可分配独立网络号(如 `10.255.0.1/32`),但这是逻辑管理地址,非物理网络分配。 --- ### 总结对比 | **特性** | 传统 ABCDE 分类 | CIDR | |------------------------|-----------------------------|-------------------------------| | **地址分配粒度** | 固定块(/8、/16、/24) | 任意前缀长度(如 /12、/27)[^2] | | **地址利用率** | 低(大量浪费) | 高(按需分配)[^3] | | **路由表大小** | 庞大(无法聚合) | 精简(支超网聚合)[^1] | | **路由器网络号分配** | 每个物理网络固定一类 | 每个接口灵活配置 CIDR 块 | > 💡 **本质区别**:传统分类是**刚性划分**(如 A/B/C 类),CIDR 是**柔性划分**(基于前缀长度),通过数学优化 $n$ 值最大化地址利用率[^2][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值