恶心的DP啊
题解网上很多,就不说了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define REP(i, a, b) for(int i = (a); i <= (b); ++i)
#define sum(i, l, r) (g[i][r] - g[i][l-1])
#define code(l, r, opl, opr) ((l << 12) + (r << 8) + (opl << 4) + (opr))
#define encode(s) (s >> 12) & 15, (s >> 8) & 15, (s >> 4) & 15, s & 15
using namespace std;
inline int read()
{
int x = 0, f = 1, t = getchar();
while(t < 48 || t > 57) t == 45 ? f = -1 : 0, t = getchar();
while(t > 47 && t < 58) x = (x << 1) + (x << 3) + t - 48, t = getchar();
return x * f;
}
typedef int Array[16][16][16][2][2][226];
int n, m, k, ans, arow, al, ar, aopl, aopr, g[16][16];
Array f, p;
//op = 0 / left
//op = 1 \ right
void expand(int row, int l, int r, int opl, int opr, int s)
{
REP(ll, opl == 0 ? 1 : l, r) REP(rr, max(l, ll), opr == 1 ? m : r)
{
int opll = (ll == l ? opl : (ll < l ? 0 : 1));
int oprr = (rr == r ? opr : (rr < r ? 0 : 1));
int &res = f[row + 1][ll][rr][opll][oprr][s+(rr-ll+1)];
int tmp = f[row][l][r][opl][opr][s] + sum(row+1, ll, rr);
if(res < tmp) res = tmp, p[row + 1][ll][rr][opll][oprr][s+(rr-ll+1)] = code(l, r, opl, opr);
}
}
void write(int row, int l, int r, int opl, int opr, int s)
{
if(row == 0 || s <= 0) return ;
int pp = p[row][l][r][opl][opr][s];
write(row-1, encode(pp), s-(r-l+1));
REP(i, l, r) printf("%d %d\n", row, i);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
n = read(), m = read(), k = read();
REP(i, 1, n) REP(j, 1, m) g[i][j] = g[i][j-1] + read();
memset(f, -1, sizeof(f));
REP(row, 1, n) REP(l, 1, m) REP(r, l, m) REP(opl, 0, 1) REP(opr, 0, 1)
{
f[row][l][r][opl][opr][r-l+1] = sum(row, l, r);
REP(s, r-l+1, k)
{
int &res = f[row][l][r][opl][opr][s];
if(res > 0)
{
if(row < n) expand(row, l, r, opl, opr, s);
if(s == k && res > ans) ans = res, arow = row, al = l, ar = r, aopl = opl, aopr = opr;
}
}
}
printf("Oil : %d\n", ans);
write(arow, al, ar, aopl, aopr, k);
#ifndef ONLINE_JUDGE
fclose(stdin), fclose(stdout);
#endif
return 0;
}