「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 1n,k500

思路

首先注意到,用完球一定比不用完球更优,即使最后有容器没装满。

以下不妨简记, 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 ansup
其次,我们忽略容器里的小球来自于同一个盒子的情况,此时答案为 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 ansdown
注意到, u p − d o w n ≤ 1 up - down \leq 1 updown1,证明略。

因此,如果 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+kr1,那么这部分装满了 x 1 + x 2 + 1 x1 + x2 + 1 x1+x2+1 个容器。

此时还剩下 s u m 1 − A sum1 - A sum1A 个红球和 s u m 2 − B sum2 - B sum2B 个蓝球。
注意到:如果 r 1 ≤ r a r1 \le ra r1ra k − r 1 ≤ r b k - r1 \le rb kr1rb ,即 r 1 ∈ [ k − r b , r a ] r1 \in [k - rb,ra] r1[krb,ra] 时,剩下的红球可以装满 ⌊ s u m 1 k ⌋ − x 1 \lfloor \frac{sum1}{k} \rfloor - x1 ksum1x1 个容器,剩下的蓝球可以装满 ⌊ s u m 2 k ⌋ − x 2 \lfloor \frac{sum2}{k} \rfloor - x2 ksum2x2 个容器,总共就可以装满 ⌊ 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] [krb,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[krb,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;
}
posted @ 2024-04-08 21:39  Fracture_Dream  阅读(14)  评论(0)    收藏  举报  来源