「Phoenix and Berries」Solution
简述题意
有 n n n 个盒子,每个盒子里有 a i a_i ai 个红球和 b i b_i bi 个蓝球。现有无数个可以装 k k k 个小球的容器,规定容器里的球必须满足以下条件之一:
- 来自同一个盒子
- 颜色相同
不必用完所有小球,问最多能装满多少个容器。
- 1 ≤ n , k ≤ 500 1 \le n,k \le 500 1≤n,k≤500
思路
首先注意到,用完球一定比不用完球更优,即使最后有容器没装满。
以下不妨简记, s u m 1 = ∑ i = 1 n a i sum1=\sum_{i=1}^{n}a_i sum1=∑i=1nai, s u m 2 = ∑ i = 1 n b i sum2=\sum_{i=1}^{n}b_i sum2=∑i=1nbi
注意到,如果我们忽略限制,答案为
u
p
=
⌊
s
u
m
1
+
s
u
m
2
k
⌋
up = \lfloor \frac{sum1+sum2}{k} \rfloor
up=⌊ksum1+sum2⌋。那么显然有:
a
n
s
≤
u
p
ans \leq up
ans≤up。
其次,我们忽略容器里的小球来自于同一个盒子的情况,此时答案为
d
o
w
n
=
⌊
s
u
m
1
k
⌋
+
⌊
s
u
m
2
k
⌋
down= \lfloor \frac{sum1}{k} \rfloor + \lfloor \frac{sum2}{k} \rfloor
down=⌊ksum1⌋+⌊ksum2⌋,那么显然有:
a
n
s
≥
d
o
w
n
ans \geq down
ans≥down。
注意到,
u
p
−
d
o
w
n
≤
1
up - down \leq 1
up−down≤1,证明略。
因此,如果 u p = d o w n up=down up=down,那么直接输出 d o w n down down 即可。否则如果 u p = d o w n + 1 up=down+1 up=down+1,我们就需要考虑最终答案能否达到上界 u p up up。
我们先假装把相同颜色的球装在一起,不妨令 r a = s u m 1 m o d k ra = sum1 \bmod k ra=sum1modk, r b = s u m 2 m o d k rb = sum2 \bmod k rb=sum2modk。那么此时剩下了 r a ra ra 个红球, r b rb rb 个蓝球,那么我们现在的要做的,就是通过将同一个盒子的小球放在一起,尽可能消耗剩下的红球。
不妨假设,将同一个盒子里的球装入同一个容器,使用了 A A A 个红球, B B B 个蓝球,其中 A = x 1 × k + r 1 A = x1 \times k + r1 A=x1×k+r1, B = x 2 × k + k − r 1 B = x2 \times k + k - r1 B=x2×k+k−r1,那么这部分装满了 x 1 + x 2 + 1 x1 + x2 + 1 x1+x2+1 个容器。
此时还剩下
s
u
m
1
−
A
sum1 - A
sum1−A 个红球和
s
u
m
2
−
B
sum2 - B
sum2−B 个蓝球。
注意到:如果
r
1
≤
r
a
r1 \le ra
r1≤ra 且
k
−
r
1
≤
r
b
k - r1 \le rb
k−r1≤rb ,即
r
1
∈
[
k
−
r
b
,
r
a
]
r1 \in [k - rb,ra]
r1∈[k−rb,ra] 时,剩下的红球可以装满
⌊
s
u
m
1
k
⌋
−
x
1
\lfloor \frac{sum1}{k} \rfloor - x1
⌊ksum1⌋−x1 个容器,剩下的蓝球可以装满
⌊
s
u
m
2
k
⌋
−
x
2
\lfloor \frac{sum2}{k} \rfloor - x2
⌊ksum2⌋−x2 个容器,总共就可以装满
⌊
s
u
m
1
k
⌋
+
⌊
s
u
m
2
k
⌋
+
1
\lfloor \frac{sum1}{k} \rfloor + \lfloor \frac{sum2}{k} \rfloor + 1
⌊ksum1⌋+⌊ksum2⌋+1 个容器。这不正是我们想要达到的上界嘛!
因此,我们只需要判断,能否使选择的红球数对
k
k
k 取模后,范围在
[
k
−
r
b
,
r
a
]
[k-rb,ra]
[k−rb,ra] 之内。这启发我们
dp
\text{dp}
dp。
不妨令
d
p
i
,
r
dp_{i,r}
dpi,r 表示 能否 处理完前
i
i
i 个盒子之后 ,选择的红球数量对
k
k
k 取模后的值为
r
r
r。暴力
O
(
n
k
2
)
O(nk^2)
O(nk2) 转移即可。
最后,如果
∃
i
∈
[
k
−
r
b
,
r
a
]
,
d
p
n
,
i
=
1
\exist i \in [k-rb,ra],dp_{n,i}=1
∃i∈[k−rb,ra],dpn,i=1,那么证明我们可以达到答案的上界
u
p
up
up,输出
u
p
up
up 即可。否则输出
d
o
w
n
down
down 即可。
代码
非常非常非常非常非常非常非常非常非常抽象的一道题,但是代码挺好写的,这里放的是官解的代码。
//Solution 1
#include <bits/stdc++.h>
using namespace std;
int N,K;
int a[505],b[505];
bool dp[505][505]; //number of shrubs considered, "extra" red berries
int main(){
cin>>N>>K;
long long totA=0,totB=0;
for (int i=1;i<=N;i++){
cin>>a[i]>>b[i];
totA+=a[i];
totB+=b[i];
}
dp[0][0]=true;
for (int i=1;i<=N;i++){
for (int j=0;j<K;j++){
//leave a[i]%K extra red berries
dp[i][j]=dp[i-1][(j-a[i]%K+K)%K];
for (int l=0;l<=min(K-1,a[i]);l++){
//check if we can leave l extra red berries
if ((a[i]-l)%K+b[i]>=K)
dp[i][j]|=dp[i-1][(j-l+K)%K];
}
}
}
long long ans=0;
for (int i=0;i<K;i++){
if (dp[N][i])
ans=max(ans,(totA+totB-i)/K);
}
cout<<ans<<endl;
}

浙公网安备 33010602011771号