# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
252068 | anonymous | Popeala (CEOI16_popeala) | C++14 | 2091 ms | 4880 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#define MAXT 20005
#define MAXN 55
#define LL long long
#define INF ( (int) 2e9 + 1e8)
using namespace std;
int N, S, T, PT[MAXT];
char AC[MAXT][MAXN];
int Sum[MAXT], lo[MAXN], hi[MAXN];
int dp[MAXT][MAXN];
class Deque { //only sheet trust STL
int DQ[MAXT];
int l=0, r = 0; //[l,r) used
public:
void nuke() {l = r = 0;}
void putfront(int x) {
DQ[r++] = x;
}
void popfront() {r--;}
void popback() {l++;}
int Front() {
return(DQ[r-1]);
}
int Back() {
return(DQ[l]);
}
int Size() {return(r-l);}
} DQ[MAXN];
int popcount(LL x) {
int res = 0;
while (x) {
res += x & 1LL;
x >>= 1;
}
return(res);
}
class SparseTable {
LL ST[MAXT][16];
int lg[MAXT];
public:
void init() {
for (int i=2; i<=T+3; i++) {
lg[i] = lg[i/2] + 1;
}
for (int i=1; i<=T; i++) {
for (int j=1; j<=N; j++) {
if (AC[i][j] == '0') {
ST[i][0] |= 1LL << j;
}
}
}
for (int i=1; i<=15; i++) {
for (int j=0; j<=T; j++) {
ST[j][i] = ST[j][i-1] | ST[j + (1 << (i-1))][i-1];
}
}
}
int Num(int l, int r) {
int lvl = lg[r - l + 1];
return(popcount(ST[l][lvl] | ST[r - (1 << lvl) + 1][lvl]));
}
} ST;
void add(int q, int p, int j) {
while (DQ[q].Size()) {
int vnew = dp[p][j-1] - Sum[p] * (N-q);
int vold = dp[DQ[q].Front()][j-1] - (N-q) * Sum[DQ[q].Front()];
if (vold >= vnew) {DQ[q].popfront();}
else {break;}
}
DQ[q].putfront(p);
}
int main() {
//freopen("popeala.in","r",stdin);
//freopen("popeala.out","w",stdout);
scanf("%d %d %d",&N,&T,&S);
for (int i=1; i<=T; i++) {
scanf("%d",&PT[i]);
}
for (int i=1; i<=N; i++) {
for (int j=1; j<=T; j++) {
scanf("\n%c\n",&AC[j][i]);
}
}
for (int i=1; i<=T; i++) {
dp[i][0] = INF; //inf big enough ?
Sum[i] = Sum[i-1] + PT[i];
}
ST.init();
for (int j=1; j<=S; j++) {
for (int i=0; i<=N; i++) {
DQ[i].nuke();
lo[i] = 0, hi[i] = -1;
}
dp[0][j] = INF;
for (int i=1; i<=T; i++) {
hi[0]++;
add(0, i-1, j);
dp[i][j] = INF;
for (int q=0; q <= N; q++) {
while (lo[q] <= hi[q]) {
if (ST.Num(lo[q]+1, i) != q) {
if (DQ[q].Size() && DQ[q].Back() == lo[q]) {
DQ[q].popback();
}
add(q+1, lo[q], j);
lo[q]++;
hi[q+1]++;
} else {
break;
}
}
if (DQ[q].Size() && dp[DQ[q].Back()][j-1] - (N-q) * Sum[DQ[q].Back()] <= INF - (N-q) * Sum[i]) {
dp[i][j] = min(dp[i][j], dp[DQ[q].Back()][j-1] + (N-q) * (Sum[i] - Sum[DQ[q].Back()]));
}
}
}
printf("%d\n",dp[T][j]);
}
}
Compilation message (stderr)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |