I-区域

在 N*M 的矩阵中,每个格子有一个权值,要求寻找一个包含 K 个格子的凸连通块(连通块中间没有空缺,并且轮廓是凸的),使这个连通块中的格子的权值和最大。

注意:凸连通块是指:连续的若干行,每行的左端点列号先递减、后递增,右端点列号先递增、后递减。

求出这个最大的权值和,并给出连通块的具体方案,输出任意一种方案即可。

输入格式
第一行包含三个整数N,M和K。

接下来N行每行M个整数,表示N*M的矩阵上每个格子的权值(均不超过1000)。

输出格式
第一行输出“Oil : X”,其中X为最大权值和。

接下来K行每行两个整数xi和yi,用来描述所有格子的具体位置,每个格子位于第xi行,第yi列。

数据范围
1≤N,M≤15,
0≤K≤N∗M

输入样例:
2 3 4 
10 20 30 
40 2 3
输出样例:
Oil : 100 
1 1 
1 2 
1 3 
2 1

注意在状态转移的时候要确保当前行的区域要和上一行的区域连通。

#include<bits/stdc++.h>

using namespace std;
const int N = 16;
int f[N][N * N][N][N][2][2];
struct P {
    int i, j, l, r, x, y;
} g[N][N * N][N][N][2][2];
int n, m, k, w[N][N];

int main() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", &w[i][j]), w[i][j] += w[i][j - 1];
    for (int i = 1; i <= n; i++)
        for (int l = 1; l <= m; l++)
            for (int r = l; r <= m; r++) {
                int L = r - l + 1, delta = w[i][r] - w[i][l - 1];
                for (int j = r - l + 1; j <= k; j++) {
                    {
                        int &vf = f[i][j][l][r][0][0];
                        P &vg = g[i][j][l][r][0][0];
                        for (int p = l; p <= r; p++)
                            for (int q = p; q <= r; q++) {
                                int val = f[i - 1][j - L][p][q][0][0];
                                if (vf < val) {
                                    vf = val;
                                    vg = {i - 1, j - L, p, q, 0, 0};
                                }
                            }
                        vf += delta;
                    }
                    {
                        int &vf = f[i][j][l][r][0][1];
                        P &vg = g[i][j][l][r][0][1];
                        for (int p = l; p <= r; p++)
                            for (int q = r; q <= m; q++)
                                for (int y = 0; y <= 1; y++) {
                                    int val = f[i - 1][j - L][p][q][0][y];
                                    if (vf < val) {
                                        vf = val;
                                        vg = {i - 1, j - L, p, q, 0, y};
                                    }
                                }
                        vf += delta;
                    }
                    {
                        int &vf = f[i][j][l][r][1][0];
                        P &vg = g[i][j][l][r][1][0];
                        for (int p = 1; p <= l; p++)
                            for (int q = l; q <= r; q++)
                                for (int x = 0; x <= 1; x++) {
                                    int val = f[i - 1][j - L][p][q][x][0];
                                    if (vf < val) {
                                        vf = val;
                                        vg = {i - 1, j - L, p, q, x, 0};
                                    }
                                }
                        vf += delta;
                    }
                    {
                        int &vf = f[i][j][l][r][1][1];
                        P &vg = g[i][j][l][r][1][1];
                        for (int p = 1; p <= l; p++)
                            for (int q = r; q <= m; q++)
                                for (int x = 0; x <= 1; x++)
                                    for (int y = 0; y <= 1; y++) {
                                        int val = f[i - 1][j - L][p][q][x][y];
                                        if (vf < val) {
                                            vf = val;
                                            vg = {i - 1, j - L, p, q, x, y};
                                        }
                                    }
                        vf += delta;
                    }
                }
            }
    int rf = 0;
    P rg;
    for (int i = 0; i <= n; i++)
        for (int l = 1; l <= m; l++)
            for (int r = l; r <= m; r++)
                for (int x = 0; x <= 1; x++)
                    for (int y = 0; y <= 1; y++) {
                        int val = f[i][k][l][r][x][y];
                        if (val > rf) {
                            rf = val;
                            rg = {i, k, l, r, x, y};
                        }
                    }
    printf("Oil : %d\n", rf);
    while (rg.j) {
        for (int j = rg.l; j <= rg.r; j++)
            printf("%d %d\n", rg.i, j);
        rg = g[rg.i][rg.j][rg.l][rg.r][rg.x][rg.y];
    }
    return 0;
}
发布了329 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/104708542