【力扣周赛】第 117 场双周赛(⭐数学、容斥原理)

竞赛链接

https://leetcode.cn/contest/biweekly-contest-117/

Q1:2928. 给小朋友们分糖果 I

https://leetcode.cn/problems/distribute-candies-among-children-i/description/
在这里插入图片描述

提示:
1 <= n <= 50
1 <= limit <= 50

竞赛时代码

拆分问题,枚举第一个人的糖果数,累加 另外两人的方案数。

class Solution {
    public int distributeCandies(int n, int limit) {
        int ans = 0;
        // 枚举分给第一个小朋友的糖果
        for (int i = 0; i <= Math.min(n, limit); ++i) {
            ans += op(n - i, limit);
        }
        return ans;
    }
    
    // 计算两个人分n个糖果的方案数
    public int op(int n, int l) {
        // 计算可获得的最小值和最大值,另一个人随之确定
        int mx = Math.min(n, l), mn = Math.max(n - l, 0);
        return Math.max(0, mx - mn + 1);
    }
}

Q2:100127. 给小朋友们分糖果 II

https://leetcode.cn/problems/distribute-candies-among-children-ii/description/
在这里插入图片描述

提示:
1 <= n <= 10^6
1 <= limit <= 10^6

竞赛时代码——枚举第一个人,求两个人的最大值最小值

class Solution {
    public long distributeCandies(int n, int limit) {
        long ans = 0;
        // 枚举分给第一个小朋友的糖果
        for (int i = 0; i <= Math.min(n, limit); ++i) {
            ans += op(n - i, limit);
        }
        return ans;
    }
    
    // 计算两个人分n个糖果的方案数
    public long op(int n, int l) {
        // 计算可获得的最小值和最大值,另一个人随之确定
        int mx = Math.min(n, l), mn = Math.max(n - l, 0);
        return Math.max(0, mx - mn + 1);
    }
}

解法2—— O ( 1 ) O(1) O(1) 容斥原理🐂

https://leetcode.cn/problems/distribute-candies-among-children-ii/solutions/2522969/o1-rong-chi-yuan-li-pythonjavacgo-by-end-2woj/

合法方案数 = 总方案数 - 不合法方案数

在这里插入图片描述
n + 2
n - (limit + 1) + 2
n - 2 * (limit + 1) + 2
n - 3 * (limit + 1) + 2

class Solution {
    public int distributeCandies(int n, int limit) {
        int a = c2(n + 2);              // n+2的位置放2个板子
        int b = 3 * c2(n - limit + 1);  // 至少一个>limit的情况
        int c = 3 * c2(n - 2 * limit);  // 至少两个>limit的情况
        int d = c2(n - 3 * limit - 1);  // 至少三个>limit的情况
        return a - b + c - d;
    }

    public int c2(int n) {
        return n > 1? n * (n - 1) / 2: 0;
    }
}

Q3:2930. 重新排列后包含指定子字符串的字符串数目⭐⭐⭐⭐⭐(数学、容斥原理)

https://leetcode.cn/problems/number-of-strings-which-can-be-rearranged-to-contain-substring/description/
在这里插入图片描述

提示:
1 <= n <= 10^5

解法—— O ( l o g n ) O(log n) O(logn) 容斥原理⭐⭐⭐⭐⭐

https://leetcode.cn/problems/number-of-strings-which-can-be-rearranged-to-contain-substring/solutions/2522964/olog-n-rong-chi-yuan-li-fu-ji-yi-hua-sou-okjf/
在这里插入图片描述
总共的方案数
2 6 n 26^n 26n

不满足的方案数
不含 l、不含t、不含e、只含一个e

  1. 不含l: 2 5 n 25^n 25n
  2. 不含t: 2 5 n 25^n 25n
  3. 不含e 或 只含一个e: 2 5 n 25^n 25n + n ∗ 2 5 n − 1 n*25^{n-1} n25n1

重复了两个组合需要去掉

  1. 不含 l 和 t: 2 4 n 24^n 24n
  2. 不含 l 和 e 最多含一个: 2 4 n + n ∗ 2 4 n − 1 24^n+n*24^{n-1} 24n+n24n1
  3. 不含 t 和 e 最多含一个: 2 4 n + n ∗ 2 4 n − 1 24^n+n*24^{n-1} 24n+n24n1

重复了两两组合的两两组合

  1. 不含 l 和 t 且 e 最多含一个: 2 3 n + n ∗ 2 3 ( n − 1 ) 23^n+n*23^{(n-1)} 23n+n23(n1)

最后结果为 2 6 n − { 2 5 n + 2 5 n + 2 5 n + n ∗ 2 5 n − 1 − 2 4 n − 2 4 n − n ∗ 2 4 n − 1 − 2 4 n − n ∗ 2 4 n − 1 + 2 3 n + n ∗ 2 3 ( n − 1 ) } 26^n-\{25^n+25^n + 25^n + n*25^{n-1} -24^n-24^n-n*24^{n-1}-24^n-n*24^{n-1}+23^n+n*23^{(n-1)}\} 26n{25n+25n+25n+n25n124n24nn24n124nn24n1+23n+n23(n1)}
= 2 6 n − 3 ∗ 2 5 n − n ∗ 2 5 n − 1 + 3 ∗ 2 4 n + 2 ∗ n ∗ 2 4 n − 1 − 2 3 n − n ∗ 2 3 n − 1 26^n-3*25^n-n*25^{n-1}+3*24^n+2*n*24^{n-1}-23^n-n*23^{n-1} 26n325nn25n1+324n+2n24n123nn23n1
= 2 6 n − ( 3 ∗ 25 + n ) ∗ 2 5 n − 1 + ( 3 ∗ 24 + 2 ∗ n ) ∗ 2 4 n − 1 − ( 23 + n ) 2 3 n − 1 26^n-(3*25+n)*25^{n-1}+(3*24+2*n)*24^{n-1}-(23+n)23^{n-1} 26n(325+n)25n1+(324+2n)24n1(23+n)23n1

转换成代码如下:

class Solution {
    final long MOD = (long)1e9 + 7;

    public int stringCount(int n) {
        long ans = ((pow(26, n) - pow(25, n - 1) * (75 + n) + pow(24, n - 1) * (72 + 2 * n) - pow(23, n - 1) * (23 + n)) % MOD + MOD) % MOD;
        return (int)ans;
    }

    public long pow(long x, long n) {
        long res = 1;
        while (n != 0) {
            if (n % 2 == 1) res = (res * x) % MOD;
            x = (x * x) % MOD;
            n >>= 1;
        }
        return res;
    }
}

Q4:2931. 购买物品的最大开销(贪心)

https://leetcode.cn/problems/maximum-spending-after-buying-items/description/
在这里插入图片描述

提示:
1 <= m == values.length <= 10
1 <= n == values[i].length <= 10^4
1 <= values[i][j] <= 10^6
values[i] 按照非递增顺序排序。

竞赛时代码——贪心

每次先取最小的购买即可。

class Solution {
    public long maxSpending(int[][] values) {
        long ans = 0;
        int m = values.length, n = values[0].length;
        int[] idx = new int[m];
        Arrays.fill(idx, n - 1);
        for (long d = 1; d <= m * n; ++d) {
            int id_m = 0;
            for (int i = 0; i < m; ++i) {
                if (idx[i] >= 0) {
                    id_m = i;
                    break;
                }
            }
            for (int i = 0; i < m; ++i) {
                if (idx[i] >= 0 && values[i][idx[i]] < values[id_m][idx[id_m]]) id_m = i;
            }
            ans += d * values[id_m][idx[id_m]];
            idx[id_m]--;
        }
        return ans;
    }
}

优化——一起排序

注意到题目中 第 i 个商店的物品已经按照价值非递增排好序了
因此,在这里插入图片描述
可以把所有的数字一起排序。

class Solution {
    public long maxSpending(int[][] values) {
        int m = values.length, n = values[0].length;
        int[] a = new int[m * n];
        int i = 0;
        for (int[] row : values) {
            System.arraycopy(row, 0, a, i, n);
            i += n;
        }
        Arrays.sort(a);
        long ans = 0;
        for (i = 0; i < a.length; i++) {
            ans += (long) a[i] * (i + 1);
        }
        return ans;
    }
}

成绩记录

在这里插入图片描述
T3 没想出来怎么写。
在这里插入图片描述

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wei *

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值