Submission #377418

#TimeUsernameProblemLanguageResultExecution timeMemory
377418kartelSelotejp (COCI20_selotejp)C++14
110 / 110
260 ms8448 KiB
#include <bits/stdc++.h>
#define in(x) freopen(x, "r", stdin)
#define out(x) freopen(x, "w", stdout)
//#include <time.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-O3")
#define F first
#define S second
#define pb push_back
//#define M ll(1e9 + 7)
#define M ll(998244353)
#define sz(x) (int)x.size()
#define re return
#define oo ll(1e18)
#define el '\n'
#define pii pair <int, int>
#define all(x) (x).begin(), (x).end()
#define arr_all(x, n) (x + 1), (x + 1 + n)
#define vi vector<int>
#define eps (ld)1e-9
using namespace std;
typedef long long ll;
//using namespace __gnu_pbds;
//typedef tree <ll, null_type, less_equal <ll> , rb_tree_tag, tree_order_statistics_node_update> ordered_set;
typedef double ld;
typedef unsigned long long ull;
typedef short int si;

const int N = 1e3 + 50;
const int MASK = (1 << 12);

char c;
int n, m;
int f[N][MASK];
int cnt[MASK], cr[MASK];
int a[N][20];

int main()
{
//    mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());;
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
//	in("toys.in");
//	out("toys.out");
//    in("input.txt");
//    out("output.txt");
//    cerr.precision(9); cerr << fixed;

//    clock_t tStart = clock();

    cin >> n >> m;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> c;

            a[i][j] = (c == '#');
        }
    }

    for (int mask = 0; mask < (1 << m); mask++) {
        cnt[mask] = __builtin_popcount(mask);
    }

    for (int i = 0; i <= n; i++) {
        for (int mask = 0; mask < (1 << m); mask++) {
            f[i][mask] = 1e9;
        }
    }

    f[0][0] = 0;

    for (int i = 1; i <= n; i++) {

        for (int mask = (1 << m) - 1; mask >= 0; mask--) {
            for (int sub = mask; sub > 0; sub = mask & (sub - 1)) {
                f[i - 1][sub] = min(f[i - 1][sub], f[i - 1][mask]);
            }
            f[i - 1][0] = min(f[i - 1][0], f[i - 1][mask]);
        }

        for (int mask = 0; mask < (1 << m); mask++) {
            bool badmask = 0;

            for (int j = 0; j < m; j++) {
                if (!a[i][j] && (mask & (1 << j))) {
                    badmask = 1;
                    break;
                }
            }

            if (badmask) {
                continue;
            }

            int cur = 0;
            int pr = 0;

            for (int j = 0; j < m; j++) {
                if (a[i][j] && !(mask & (1 << j))) {
                    if (!pr) {
                        cur++;
                    }

                    pr = 1;
                }
                else  {
                    pr = 0;
                }
            }

            cr[mask] = cur;

        }

        for (int mask = 0; mask < (1 << m); mask++) {

            bool bad = 0;

            for (int j = 0; j < m; j++) {
                if (!a[i][j] && (mask & (1 << j))) {
                    bad = 1;
                    break;
                }
            }

            if (bad) {
                continue;
            }
            f[i][mask] = min(f[i][mask], f[i - 1][0] + cnt[mask] + cr[mask]);

            for (int sub = mask; sub; sub = (mask & (sub - 1))) {
                f[i][mask] = min(f[i][mask], f[i - 1][sub] + cr[mask] + cnt[mask] - cnt[sub]);
            }
        }
    }

    cout << *min_element(f[n], f[n] + (1 << m));
}
/*
20 8
..###.##
.##.#.##
##.##...
#..#..##
#..##.##
##..##..
.#...###
.####..#
#...####
###.....
..######
........
##.####.
##.#..##
...##..#
##..#.##
#.###.#.
#.#...##
#.####.#
##...###

1 2 4 8 16 32 64 128 256 512
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...