2019牛客多校第二场
D.Kth Minimum Clique(dijkstra+bitset+二进制)
- 题意:从图中随机选几个点,如果这些点连通,那么就称为团.团的价值是所有点的和.求第\(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;
}
Second Large Rectangle(单调栈+思维)
-
题意:第二大的全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;
}