比赛 防止颓废的小练习v0.1 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 子矩阵 最终得分 100
用户昵称 rewine 运行时间 0.318 s
代码语言 C++ 内存使用 0.30 MiB
提交时间 2016-10-17 11:25:50
显示代码纯文本
#include <stdio.h>
#include <stdlib.h>

#define INF 1000000000

int n, m, row, col;
int answer = INF;

int matrix[20][20];
int scoreCol[20]; //scoreCol[i] = score of column i
int score2Col[20][20];  //score2Col[i][j] = additional score when column i & column j be combined
int f[20][20];

int MIN(int a, int b){
    return a<b ? a:b;
}
int DP(int rowStatus){
    int i, j, k, fMin = INF;
    int rows[20];

    j = 0;
    for(i=0; i<n; i++){
        if((rowStatus>>i) & 1)
            rows[j++] = i;
    }
    for(i=0; i<m; i++){
        scoreCol[i] = 0;
        for(j=1; j<row; j++)
            scoreCol[i] += abs(matrix[rows[j]][i] - matrix[rows[j-1]][i]);

        for(j=i+1; j<m; j++){
            score2Col[i][j] = 0;
            for(k=0; k<row; k++)
                score2Col[i][j] += abs(matrix[rows[k]][j] - matrix[rows[k]][i]);
        }
    }

    for(i=0; i<m; i++){
        for(j=0; j<m; j++)
            f[i][j] = INF;
    }
    for(j=0; j<m; j++)
        f[1][j] = scoreCol[j];

    for(i=2; i<=col; i++){  //i columns have been selected
        for(j=i-1; j<m; j++){  //current column
            for(k=0; k<j; k++)  //previous column
                f[i][j] = MIN(f[i][j], f[i-1][k] + scoreCol[j] + score2Col[k][j]);
        }
    }

    for(j=0; j<m; j++)
        fMin = MIN(fMin, f[col][j]);

    return fMin;
}
void solve(int depth, int status, int rowLeft){
    if(depth >= n){
        if(rowLeft == 0)
            answer = MIN(answer, DP(status));
    }else{
        if(rowLeft > 0)
            solve(depth+1, (status<<1)|1, rowLeft-1);
        if(rowLeft <= n-depth)
            solve(depth+1, status<<1, rowLeft);
    }
}
int main(){
	freopen("submatrix.in","r",stdin);
   freopen("submatrix.out","w",stdout);
    int i, j;
    scanf("%d %d %d %d", &n, &m, &row, &col);
    for(i=0; i<n; i++){
        for(j=0; j<m; j++)
            scanf("%d", &matrix[i][j]);
    }
    solve(0, 0, row);
    printf("%d\n", answer);
    return 0;
}