2019牛客多校第二场

匿名 (未验证) 提交于 2019-12-02 23:49:02
  • 题意:从图中随机选几个点,如果这些点连通,那么就称为团.团的价值是所有点的和.求第\(k\)小的团.
  • 一开始想到\(2^n\)的算法
  • 如果从合法状态然后增广,就可以避免走到很多非法状态,然后用一个last避免重复
  • cin>>bit[i] bitset不能这样输入
#include<bits/stdc++.h>  #define ll long long using namespace std; const int maxn = 105; ll s[maxn]; bitset<100> bit[maxn]; int n, k;  struct node {     bitset<100> now;     int last = 0;     ll val = 0;      node(bitset<100> _now = 0, int _last = 0, ll _val = 0) {         now = _now;         last = _last;         val = _val;     }      bool operator<(const node &c) const {         return val > c.val;     } };  priority_queue<node> que;  ll dijkstra() {     node st;     st.now.reset();     que.push(st);     while (!que.empty()) {         st = que.top();         que.pop();         if (--k == 0) {             return st.val;         }         for (int i = st.last; i < n; ++i) {             if (!st.now[i] && ((st.now & bit[i]) == st.now)) {                 st.now.set(i);                 que.push(node(st.now, i + 1, st.val + s[i]));                 st.now.reset(i);             }         }     }     return -1; }  int main() {     ios::sync_with_stdio(false);     cin.tie(0);     cin >> n >> k;     string str;     for (int i = 0; i < n; ++i) cin >> s[i];     for (int i = 0; i < n; ++i) {         cin >> str;         for (int j = 0; j < n; ++j) {             if (str[j] == '1')bit[i].set(j);             else bit[i].reset(j);         }     }     cout << dijkstra() << endl;     return 0; }
  • 题意:第二大的全1子矩阵

  • 求第一大的会,算法竞赛进阶上有模板.直接通过单调栈即可.

  • 然后这题我也直接套了模板,但是错了

  • 没考虑这个样例

  •  

    3 3
    101
     111
     111

  • 因为他有一个合并的操作,然后我一开始的写法不会出现4,要搞一个width-1才行

#include "bits/stdc++.h"  using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int maxn = 1010; const int inf = 0x3f3f3f3f; char s[maxn][maxn]; int sum[maxn]; int que[maxn]; int w[maxn];  int main() {     //freopen("in.txt", "r", stdin);     int n, m;     scanf("%d%d", &n, &m);     for (int i = 0; i < n; ++i) {         scanf("%s", s[i]);     }     int top;     int maxx = 0, cmaxx = 0;     for (int i = 0; i < n; ++i) {         top = 0;         for (int j = 0; j < m; ++j) {             w[j] = 0;             if (s[i][j] == '1') {                 sum[j] += 1;             } else sum[j] = 0;         }         sum[m] = 0;         for (int j = 0; j <= m; ++j) {             if (sum[j] > que[top]) {                 que[++top] = sum[j];                 w[top] = 1;             } else {                 int width = 0;                 while (sum[j] < que[top]) {                     width += w[top];                     if ((width - 1) * que[top] > maxx) {                         cmaxx = maxx;                         maxx = (width - 1) * que[top];                     } else if ((width - 1) * que[top] > cmaxx) {                         cmaxx = (width - 1) * que[top];                     }                     if (width * que[top] > maxx) {                         cmaxx = maxx;                         maxx = width * que[top];                     } else if (width * que[top] > cmaxx) {                         cmaxx = width * que[top];                     }                     top--;                 }                 que[++top] = sum[j];                 w[top] = width + 1;             }         }     }     printf("%d\n", cmaxx);     return 0; } 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!