zoukankan      html  css  js  c++  java
  • CodeForces Div3.F

    CodeForces Div3.F - Zero Remainder Sum

    题意

    给定一个 (n imes m)的矩阵,你可以在每一行选择不多于(frac{n}{2})个元素,使得整体选择的元素的和模(k)为0,并且和越大越好。

    [1leq n,m,kleq 70\ 1leq a_{ij} leq 70 ]

    分析

    据说是一道标准的动态规划问题。

    (dp[x][y][cnt][rem])表示当前在(i,j),当前行已经选取了(cnt)个元素并且当前的余数是(rem)

    初始化(dp)为负无穷,(dp[0][0][0][0] = 0)

    状态转移

    [dp[nx][ny][cnt][rem] = max(dp[nx][ny][cnt][rem],dp[x][y][cnt][rem]) 表示不取当前元素\ dp[nx][ny][cnt + 1][(rem+a_{ij})\%k] = max(dp[nx][ny][cnt+1][(rem+a_{ij})\%k],dp[x][y][cnt][rem] + a_{ij}) 表示取当前元素 ]

    答案就是(max(dp[n][0][0][0],0)),这里可以认为是最后一行的下一行的第一个元素

    注意一下实现的时候直接套上四个(for)就行了

    代码

    const int M = 70;
    
    int a[M][M];
    int dp[M][M][M][M];
    
    int main() {
        int n = readint();
        int m = readint();
        int k = readint();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                a[i][j] = readint();
        memset(dp, -INF, sizeof dp);
        dp[0][0][0][0] = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int cnt = 0; cnt < m / 2 + 1; cnt++) {
                    for (int rem = 0; rem < k; rem++) {
                        if (dp[i][j][cnt][rem] == -INF) continue;
                        int nx = (j == m - 1 ? i + 1 : i);
                        int ny = (j == m - 1 ? 0 : j + 1);
                        if (i != nx)
                            dp[nx][ny][0][rem] = max(dp[nx][ny][0][rem], dp[i][j][cnt][rem]);
                        else
                            dp[nx][ny][cnt][rem] = max(dp[nx][ny][cnt][rem], dp[i][j][cnt][rem]);
                        if (cnt + 1 <= m / 2) {
                            int nrem = (rem + a[i][j]) % k;
                            if (i != nx)
                                dp[nx][ny][0][nrem] = max(dp[nx][ny][0][nrem], dp[i][j][cnt][rem] + a[i][j]);
                            else
                                dp[nx][ny][cnt + 1][nrem] = max(dp[nx][ny][cnt + 1][nrem], dp[i][j][cnt][rem] + a[i][j]);
                        }
                    }
                }
            }
        }
        cout << max(0,dp[n][0][0][0]);
    }
    
  • 相关阅读:
    HTTP的KeepAlive是开启还是关闭?
    JS中关于in运算符的问题
    关于jQuery的inArray 方法介绍
    JS中括号的用法
    关于js中for in的缺陷浅析
    Ajax datatype:'JSON'的error问题Status1:200,JSON格式
    windows 如何查看端口占用情况?
    确认过眼神,看清 HTTP 协议
    高考完?入门级的开源项目带你开启编程之旅
    MongoDB入门系列(四):权限管理
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13854789.html
Copyright © 2011-2022 走看看