zoukankan      html  css  js  c++  java
  • [Codeforces 946D]Timetable

    Description

    题库链接

    给你一个 (N imes M)(01) 矩阵,你可以从中将一些 (1) 变为 (0) ,最多 (K) 次。使操作之后使得每行最远的 (1) 间距和最小。输出最小值。

    (1leq N,M,Kleq 500)

    Solution

    显然可以预处理一个数组 (a_{i,j}) 表示第 (i) 行操作 (j) 次后最小的间距。这个可以用 (O(N^3)) 枚举出来的。

    其次记 (f_{i,j}) 表示前 (i) 行操作 (j) 次后,最小间距和,也是 (O(N^3))(DP)

    最后答案就是 (minlimits_{i=1}^k f_{n,i})

    Code

    //It is made by Awson on 2018.3.10
    #include <bits/stdc++.h>
    #define LL long long
    #define dob complex<double>
    #define Abs(a) ((a) < 0 ? (-(a)) : (a))
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
    #define writeln(x) (write(x), putchar('
    '))
    #define lowbit(x) ((x)&(-(x)))
    using namespace std;
    const int N = 500, INF = ~0u>>1;
    void read(int &x) {
        char ch; bool flag = 0;
        for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
        for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
        x *= 1-2*flag;
    }
    void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
    void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
    
    int n, m, k, a[N+5][N+5], b[N+5], top, len, l[N+5];
    char ch[N+5];
    int f[N+5][N+5];
    
    void get_a(int id) {
        a[id][top] = 0;
        for (int i = 1; i <= top; i++)
        for (int j = 1; j+i-1 <= top; j++)
            a[id][top-i] = Min(a[id][top-i], b[j+i-1]-b[j]+1);
    }
    void work() {
        read(n), read(m), read(k);
        memset(a, 127/3, sizeof(a)); memset(f, 127/3, sizeof(f));
        for (int i = 1; i <= n; i++) {
        scanf("%s", ch); top = 0, len = strlen(ch);
        for (int j = 0; j < len; j++) if (ch[j] == '1') b[++top] = j;
        get_a(i); l[i] = top;
        }
        f[0][0] = 0;
        for (int i = 1; i <= n; i++)
        for (int j = 0; j <= k; j++)
            for (int q = 0; q <= j; q++)
            f[i][j] = Min(f[i][j], f[i-1][q]+a[i][j-q]);
        int ans = INF; for (int i = 0; i <= k; i++) ans = Min(ans, f[n][i]);
        printf("%d
    ", ans);
    }
    int main() {
        work(); return 0;
    }
  • 相关阅读:
    Codeforces Beta Round #92 (Div. 2 Only) B. Permutations 模拟
    POJ 3281 Dining 最大流 Dinic算法
    POJ 2441 Arrange the BUlls 状压DP
    URAL 1152 Faise Mirrors 状压DP 简单题
    URAL 1039 Anniversary Party 树形DP 水题
    URAL 1018 Binary Apple Tree 树形DP 好题 经典
    pytorch中的forward前向传播机制
    .data()与.detach()的区别
    Argparse模块
    pytorch代码调试工具
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8540196.html
Copyright © 2011-2022 走看看