AtCoder Beginner Contest 297 【E-F】题解

文章介绍了AtCoderBeginnerContest297中E和F两道题目的解法。E题使用了多重指针和动态规划,类似于LeetCode上的丑数问题;F题通过枚举矩形的高和宽,利用容斥原理计算最小矩形覆盖,涉及组合数学的计算。
摘要由CSDN通过智能技术生成

AtCoder Beginner Contest 297 【E-F】题解

E - Kth Takoyaki Set

多重指针,具体可参考leetcode简化版题目 丑数

import math
import sys
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from itertools import permutations

input = lambda: sys.stdin.readline().rstrip("\r\n")


def I():
    return input()


def ii():
    return int(input())


def li():
    return list(input().split())


def mi():
    return map(int, input().split())


def lii():
    return list(map(int, input().split()))

# 8 3
# 5 3
# 2 3
# 2 1
# 1 1

n,k = mi()
a = lii()
dp = [0] * (k + 1)
pois = [0] * n
i = 1
while i <= k:
    mi = float('inf')
    for j in range(n):
        mi = min(mi,dp[pois[j]] + a[j])
    for j in range(n):
        if mi == dp[pois[j]] + a[j]:
            dp[i] = mi
            pois[j] += 1
    i += 1
print(dp[k])

F - Minimum Bounding Box 2

枚举矩形的高h和宽w,通过容斥枚举不能够组成该矩形的充要条件(即有一条边没有点),一共四种情况,最上面少一条边,最下面少一条边,最左边少一天边,最右边少一条边。
然后减去重复的,此时是四容斥情况
具体容斥公式可见OI Wiki进行推导

import math
import sys
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque
from itertools import permutations

input = lambda: sys.stdin.readline().rstrip("\r\n")


def I():
    return input()


def ii():
    return int(input())


def li():
    return list(input().split())


def mi():
    return map(int, input().split())


def lii():
    return list(map(int, input().split()))


def qmi(x, y, mod):
    res = 1
    while y:
        if y & 1: res = res * x % mod
        x = x * x % mod
        y >>= 1
    return res % mod


class Factorial:
    def __init__(self, N, mod) -> None:
        N += 1
        self.mod = mod
        self.f = [1 for _ in range(N)]
        self.g = [1 for _ in range(N)]
        for i in range(1, N):
            self.f[i] = self.f[i - 1] * i % self.mod
        self.g[-1] = pow(self.f[-1], mod - 2, mod)
        for i in range(N - 2, -1, -1):
            self.g[i] = self.g[i + 1] * (i + 1) % self.mod

    def fac(self, n):
        return self.f[n]

    def fac_inv(self, n):
        return self.g[n]

    def comb(self, n, m):
        if n < m or m < 0:
            return 0
        return self.f[n] * self.g[m] % self.mod * self.g[n - m] % self.mod

    def perm(self, n, m):
        if n < m or m < 0:
            return 0
        return self.f[n] * self.g[n - m] % self.mod

    def catalan(self, n):
        return (self.comb(2 * n, n) - self.comb(2 * n, n - 1)) % self.mod

    def inv(self, n):
        return self.f[n - 1] * self.g[n] % mod


mod = 998244353
fact = Factorial(10 ** 6 + 3, mod)


def comb(x, y, k):
    if x <= 0 or y <= 0 or k < 0 or x * y < k: return 0
    return fact.comb(x * y, k)


h, w, k = lii()

ans = 0
for n in range(1, h + 1):
    for m in range(1, w + 1):
        cnt = (h - n + 1) * (w - m + 1)
        q = comb(n, m, k) - comb(n, (m - 1), k) * 2 - comb(n - 1, m, k) * 2 \
            + comb((n - 2), m, k) + comb(n, (m - 2), k) + 4 * comb((n - 1), (m - 1), k) \
            - comb((n - 2), (m - 1), k) * 2 - comb((n - 1), (m - 2), k) * 2 + comb((n - 2), (m - 2), k)
        ans += q * cnt * n * m
        ans %= mod
print(ans * qmi(fact.comb(h * w, k), mod - 2, mod) % mod)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值