诈骗系列之-CF2059C

闲话

本文同步发布在 cnblogs


容易观察到一件事,一个队列只需要进行一次服务,否则前一次就是浪费了。

这样我们就会发现,最终所有队列的长度为 \(0 \sim n - 1\) 的排列。

这样我们就会发现对于每个队列,只有最下面的 \(1\) 是有用的,原因放在了本文最后。

对于每个 \(0 \sim n - 1\) 的数 \(i\),我们都尽可能用价值较低(最下面的 \(1\) 较少)的队列满足,且还需满足 \(sum1 \ge i\),其中 \(sum1\) 表示该队列 \(1\) 的数量。

时间复杂度 \(O(n^2)\)

#include<bits/stdc++.h>
using namespace std;
long long t, n, a[305][305], b[305];
int main(){
     ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
     cin >> t;
     while(t --){
          cin >> n;
          for(int i = 1; i <= n; i ++){
               b[i] = 0;
               for(int j = 1; j <= n; j ++){
                    cin >> a[i][j];
               }
               for(int j = n; j >= 1; j --){
                    if(a[i][j] == 1) b[i] ++;//统计该队列位于有多少底部的 1
                    else break;
               }
          }
          sort(b + 1, b + n + 1); // 排序,优先使用较小的
          int ans = 0; // 注意 0 也需要满足
          for(int i = 1; i <= n; i ++){
               if(b[i] >= ans){
                    ans ++;
               }
          }
          cout << ans << "\n";
     }
     return 0;
}

最后来证明前面提到的:

对于每个队列,只有最下面的 \(1\) 是有用的

这句话的重点在于最下面的 \(1\),而不是最下面的 \(2\),若我们加入一个 \(2\),虽然这个数变大了,但是 \(\operatorname{mex}\) 要求需要一个更小的来填补,每个数都来填补,就会导致没有队列有 \(0\) 人,答案更劣,所以不可以加入其他数字。

posted on 2025-02-03 01:09  zhangzirui66  阅读(25)  评论(0)    收藏  举报

导航