总体来说本期比较简单
C - Maximum Volume
答案显然是 O ( N 3 ) O(N^3) O(N3)
D - Banned K
先统计总的,然后减去选到的那个数再重新计算
E - Dividing Chocolate
既然n范围是10,那么在n的宽度上做一个位操作,若i位与i+1位之间有切割,i位设为1,枚举横方向的切割方案,然后在竖方向上做贪心
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharmimport bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(1000)def main():items = sys.version.split()if items[0] == '3.10.6':fp = open("in.txt")else:fp = sys.stdinn, m, K = map(int, fp.readline().split())a = []for i in range(n):s = fp.readline().strip()a.append(s)sm = [[0] * m for _ in range(n + 1)]for j in range(m):for i in range(n):sm[i + 1][j] = sm[i][j] + ord(a[i][j]) - ord('0')ans = 10 ** 18for mask in range(1 << (n - 1)):last = 0temp = []div_cnt = 0ac = 1for j in range(n):if mask >> j & 1 or j == n - 1:b = []for k in range(m):x = sm[j + 1][k] - sm[last][k]if x > K:ac = 0b.append(x)last = j + 1temp.append(b)if mask >> j & 1:div_cnt += 1if ac == 0:continuel = len(temp)t = [0] * lfor j in range(m):d = 0for i in range(l):t[i] += temp[i][j]if t[i] > K:d = 1if d:div_cnt += 1for i in range(l):t[i] = temp[i][j]ans = min(ans, div_cnt)print(ans)if __name__ == "__main__":main()
F - Knapsack for All Segments
观察了一下,发现在做到 i位时,可以去计算 F ( i , s u m ) F(i, sum) F(i,sum)
其中sum是当前计算的和,F代表方案数
F ( i , s u m ) = ∑ F ( j , s u m − a [ i ] ) ∗ ( n − i ) F(i,sum)=\sum F(j,sum-a[i])*(n-i) F(i,sum)=∑F(j,sum−a[i])∗(n−i)
但是这样是 O ( N 2 ∗ S ) O(N^2*S) O(N2∗S)的三重循环,因此要记录一下前缀和 G ( s u m ) = ∑ F ( i , s u m ) G(sum)=\sum F(i,sum) G(sum)=∑F(i,sum)
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharmimport bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(1000)def main():items = sys.version.split()if items[0] == '3.10.6':fp = open("in.txt")else:fp = sys.stdinn, S = map(int, fp.readline().split())a = list(map(int, fp.readline().split()))dp = [0] * (S + 1)mod = 998244353ans = 0for i in range(n):if a[i] == S:ans += (i + 1) * (n - i)ans %= modelif S - a[i] > 0:ans += dp[S - a[i]] * (n - i)ans %= modfor j in range(S, -1, -1):if j >= a[i]:dp[j] = (dp[j] + dp[j - a[i]]) % moddp[a[i]] += i + 1dp[a[i]] %= modprint(ans)if __name__ == "__main__":main()