LeetCode 1259. Handshakes That Don't Cross - Java - DP

题目链接:https://leetcode-cn.com/problems/handshakes-that-dont-cross/



You are given an?even number of people num_people?that stand around a circle and each person shakes hands?with someone else, so that there are num_people / 2 handshakes total.

Return the number of ways these handshakes could occur such that none of the handshakes cross.

Since this number could be very big, return the answer mod?10^9 + 7

Example 1:

Input: num_people = 2
Output: 1

Example 2:

Input: num_people = 4
Output: 2
Explanation: There are two ways to do it, the first way is [(1,2),(3,4)] and the second one is [(2,3),(4,1)].

Example 3:

Input: num_people = 6
Output: 5

Example 4:

Input: num_people = 8
Output: 14

Constraints:

  • 2 <= num_people <= 1000
  • num_people % 2 == 0

题解

先分析一下示例 3,
第 6 个人和第 5 个人握手,圆被分成两部分,一部分是 4 个人,另一部分是 0 个人。0 个人的方案数为 1,4 个人的方案数可以递归计算为 2,所以这种情况有 2 种方案。
第 6 个人和第 3 个人握手,圆被分成两部分,每部分都是 2 个人,2 个人的方案数是 1,所以这种情况有 1 种方案。
第 6 个人和第 1 个人握手,圆被分成两部分,一部分是 0 个人,另一部分是 4 个人,所以这种情况有 2 中方案。
因此 6 个人的时候有 5 种方案数。@wowpH

n 个人(n为偶数),如果第 n 个人和第 ii = n - 1, n - 3, ……,1)个人握手,那么分成的两部分中,一部分有 i - 1 人,另一部分有 n - i - 1 人。这两部分又是一个新的子问题。

所以题目可以采用 动态规划(DP) 来解决。

用大小为 num_people + 1long型一维数组 arr 来保存每种人数时的方案数。公式为:
\[arr[n] = \begin{cases}
1 &\text{ } n=0或n=2 \ \displaystyle\sum_{i=1}^{n-1} (arr[i - 1] * arr[n - i - 1]) &\text{ } n>2,n为偶数,i为奇数
\end{cases}.\]


Java代码

/**
 * @description 5125. Handshakes That Don't Cross
 * @time 10ms
 * @version 1.1
 * @author wowpH
 * @date 2019-11-17 22:44:21
 */
class Solution {
    private static final int mod = 1000000007;
    private long[] arr;

    public int numberOfWays(int num_people) {
        arr = new long[num_people + 1];
        return (int) dp(num_people);
    }

    private long dp(int n) {
        if (n == 0 || n == 2) {
            return 1;
        }
        long ret = 0;
        for (int i = n - 1; i >= 1; i -= 2) {
            if (arr[i - 1] == 0) {
                arr[i - 1] = dp(i - 1);
            }
            if (arr[n - i - 1] == 0) {
                arr[n - i - 1] = dp(n - i - 1);
            }
            ret += arr[i - 1] * arr[n - i - 1];
            ret %= mod;
        }
        return ret;
    }
}


原文链接:https://www.cnblogs.com/wowpH/p/11880952.html


- wowpH -

LeetCode 1259. Handshakes That Don't Cross - Java - DP

原文地址:https://www.cnblogs.com/wowpH/p/handshakes-1259.html

时间: 2024-10-09 02:42:55

LeetCode 1259. Handshakes That Don't Cross - Java - DP的相关文章

LeetCode 1259. Handshakes That Don&#39;t Cross

一.原题描述 You are given an even number of people num_people that stand around a circle and each person shakes hands with someone else, so that there are num_people / 2 handshakes total. Return the number of ways these handshakes could occur such that no

LeetCode 57. Insert Interval 插入区间 (C++/Java)

题目: Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Input: intervals = [[1,3],[6,9]], newInter

LeetCode:零钱兑换【322】【DP】

LeetCode:零钱兑换[322][DP] 题目描述 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: coins = [1, 2, 5], amount = 11 输出: 3 解释: 11 = 5 + 5 + 1 示例 2: 输入: coins = [2], amount = 3 输出: -1 说明:你可以认为每种硬币的数量是无限的. 题目分析 很显然,这是

[LeetCode] 012. Integer to Roman (Medium) (C++/Java/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 012.Integer_to_Roman (Medium) 链接: 题目:https://oj.leetcode.com/problems/integer-to-roman/ 代码(github):https://github.com/illuz/leetcode 题意: 把十进制转为罗马数. 分析: 模拟即可.

[LeetCode] 013. Roman to Integer (Easy) (C++/Java/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 013.Roman_to_Integer (Easy) 链接: 题目:https://oj.leetcode.com/problems/roman-to-integer/ 代码(github):https://github.com/illuz/leetcode 题意: 把罗马数转为十进制. 分析: 跟 012. I

[LeetCode] 005. Longest Palindromic Substring (Medium) (C++/Java/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 005.Longest_Palindromic_Substring (Medium) 链接: 题目:https://oj.leetcode.com/problems/Longest-Palindromic-Substring/ 代码(github):https://github.com/illuz/leetcode

LeetCode【5】. Longest Palindromic Substring --java实现

Longest Palindromic Substring 一.题目如下:        Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 题目要求给定字符串的最大对称子字符串,如"aaabccbac

[LeetCode] 008. String to Integer (Easy) (C++/Java/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 008.String_to_Integer (Easy) 链接: 题目:https://oj.leetcode.com/problems/string-to-integer-atoi/ 代码(github):https://github.com/illuz/leetcode 题意: 将一个字符串转化为 int 型.

[LeetCode] 010. Regular Expression Matching (Hard) (C++/Java/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 010.Regular_Expression_Matching (Hard) 链接: 题目:https://oj.leetcode.com/problems/regular-expression-matching/ 代码(github):https://github.com/illuz/leetcode 题意: 给