80分求助
查看原帖
80分求助
1098596
WhiteNight__楼主2025/6/12 14:12
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 18;

int n , m , k;

LL f[N][N*N][N][N][2][2] , s[N][N];
bool v[N][N*N][N][N][2][2];

struct PrePath {
	int k , l , r , o1 , o2;
	
	PrePath (int k = 0 , int l = 0 , int r = 0 , int o1 = 0 , int o2 = 0):
		k(k) , l(l) , r(r) , o1(o1) , o2(o2) {}
};

PrePath pre[N][N*N][N][N][2][2];

void Print (int x , int k , int l , int r , int o1 , int o2)
{
	if(!k || x > n) return;
	PrePath &g = pre[x][k][l][r][o1][o2];
	for(int i = g.l ; i <= g.r ; i ++) printf("%d %d\n",x,i);
	Print (x+1 , g.k , g.l , g.r , g.o1 , g.o2);
}

LL dfs (int x , int k , int l , int r , int o1 , int o2)
{
	LL &fx = f[x][k][l][r][o1][o2];
	if(v[x][k][l][r][o1][o2]) return fx;
	v[x][k][l][r][o1][o2] = 1;
	if(!k || x > n) return fx = 0;
	if(!x)
	{
		for(int p = 1 ; p <= n ; p ++)
		{
			for(int i = 1 ; i <= m ; i ++)
			{
				for(int j = i ; j <= m ; j ++)
				{
					fx = max (fx , dfs (p , k , i , j , 0 , 1));
					fx = max (fx , dfs (p , k , i , j , 0 , 0));
					fx = max (fx , dfs (p , k , i , j , 1 , 0));
					fx = max (fx , dfs (p , k , i , j , 1 , 1));
				}
			}
		}
		printf("Oil : %lld\n",fx);
		bool ok = false;
		for(int i = 1 ; i <= m && !ok ; i ++)
		{
			for(int j = i ; !ok && j <= m ; j ++)
			{
				for(int p = 1 ; !ok && p <= n ; p ++)
				{
					if(fx == dfs (p , k , i , j , 0 , 1))
					{
						ok = true;
						Print (p , k , i , j , 0 , 1);
					}
					else if(fx == dfs (p , k , i , j , 0 , 0))
					{
						ok = true;
						Print (p , k , i , j , 0 , 0);
					}
					else if(fx == dfs (p , k , i , j , 1 , 0))
					{
						ok = true;
						Print (p , k , i , j , 1 , 0);
					}
					else if(fx == dfs (p , k , i , j , 1 , 1))
					{
						ok = true;
						Print (p , k , i , j , 1 , 1);
					}
				}
			}
		}
		return 1;
	}
	int Lleft , Lright , Rleft , Rright;
	LL anss , d;
	PrePath lis;
	if(o1 == 0) Lleft = 1 , Lright = l;
	else Lleft = l , Lright = m;
	
	if(o2 == 0) Rleft = 1 , Rright = r;
	else Rleft = r , Rright = m;
	
	for(int i = Lleft ; i <= Lright ; i ++)
	{
		for(int j = max(i , Rleft) ; j <= Rright && j - i + 1 <= k ; j ++)
		{
			anss = 0;
			lis = PrePath(0,i,j);
			d = dfs (x+1 , k-(j-i+1) , i , j , o1 , o2);
			if(d > anss) 
			{
				anss = d;
				lis = PrePath (k-(j-i+1) , i , j , o1 , o2);
			}
			if(o1 == 0) 
			{
				d = dfs (x+1 , k-(j-i+1) , i , j , 1 , o2);
				if(d > anss) 
				{
					anss = d;
					lis = PrePath (k-(j-i+1) , i , j , 1 , o2);
				}
			}
			if(o2 == 1) 
			{
				d = dfs(x+1 , k-(j-i+1) , i , j , o1 , 0);
				if(d > anss)
				{
					anss = d;
					lis = PrePath (k-(j-i+1) , i , j , o1 , 0);
				}
			}
			if(o1 == 0 && o2 == 1) 
			{
				d = dfs (x+1 , k-(j-i+1) , i , j , 1 , 0);
				if(d > anss)
				{
					anss = d;
					lis = PrePath (k-(j-i+1) , i , j , 1 , 0);
				}
			}
			if(anss + s[x][j] - s[x][i-1] > fx)
			{
				fx = anss + s[x][j] - s[x][i-1];
				pre[x][k][l][r][o1][o2] = lis;
			}
		}
	}
//	printf("f[%d][%d][%d][%d][%d][%d] = %d\n",x,k,l,r,o1,o2,fx);
	return fx;
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	
	for(int i = 1 ; i <= n ; i ++)
	{
		for(int j = 1 ; j <= m ; j ++)
		{
			scanf("%lld",&s[i][j]);
			s[i][j] += s[i][j-1];
		}
	}
	
	dfs (0,k,0,0,0,0);
	
	return 0;
}
2025/6/12 14:12
加载中...