题解:【ABC298G】 Strawberry War

题目链接

场上被 F 干碎了,没看见这个典题/px。原题差不多是这个吧。

注意到矩形并不大,直接用最暴力的方法做就好。设 \(f_{t,x1,y1,x2,y2}\) 表示 \((x1,y1)\)\((x2,y2)\) 这个区间切 \(t\) 刀所能获得的最小极差,然后暴力枚举当前这一刀是横着切还是竖着切,在哪个区间切,切在什么位置。我的实现使用了记搜以及前缀和快速计算区间和,需要注意的地方就是区间的开闭。

#include<bits/stdc++.h>
#define ld long double 
#define ull unsigned long long
#define int long long
#define pb push_back
#define mp make_pair
using namespace std;

inline int read()
{
	int s=0,w=1; char c=getchar();
	while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
	while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
	return s*w;
}
inline void write(int x,char ch)
{
	if(x<0) x=-x,putchar('-');
	static char stk[25]; int top=0;
	do {stk[top++]=x%10+'0',x/=10;} while(x);
	while(top) putchar(stk[--top]);
	putchar(ch);
	return;
}
inline void file()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
}

bool Mbe;

namespace MyTool
{
	static const int Mod=998244353;
	inline void Swp(int &a,int &b) {int t=a;a=b;b=t;}
	inline int  Max(int a,int b)   {return (b&((a-b)>>63))|(a&(~(a-b)>>31));}
	inline int  Min(int a,int b)   {return (a&((a-b)>>63))|(a&(~(a-b)>>31));}
	template<typename T> inline void cmax(T &a,T b) {a=a>b?a:b;}
	template<typename T> inline void cmin(T &a,T b) {a=a<b?a:b;}
	inline int  Abs(int a) {return (a^(a>>63))-(a>>63);}
	inline void Madd(int &a,int b) {a=a+b>Mod?a+b-Mod:a+b;}
	inline void Mdel(int &a,int b) {a=a-b<0?a-b+Mod:a-b;}
	inline void Mmul(int &a,int b) {a=1ll*a*b%Mod;}
	inline void Mmod(int &a) {a=(a%Mod+Mod)%Mod;}
	inline int  Cadd(int a,int b)  {return a+b>=Mod?a+b-Mod:a+b;}
	inline int  Cdel(int a,int b)  {return a-b<0?a-b+Mod:a-b;}
	inline int  Cmul(int a,int b)  {return a*b%Mod;}
	inline int  Cmod(int a)  {return (a%Mod+Mod)%Mod;}
	inline int  gcd(int a,int b)   {return b?gcd(b,a%b):a;}
	inline int  qpow(int a,int b)  {int res=1; while(b) {if(b&1) Mmul(res,a); Mmul(a,a); b>>=1;} return res;}
	inline int  qmul(int a,int b)  {int res=0; while(b) {if(b&1) Madd(res,a); Madd(a,a); b>>=1;} return res;}
	template<typename T> inline T pow(T x)    {return x*x;}
}
using namespace MyTool;

namespace LgxTpre
{
	static const int MAX=10;
	static const int inf=2147483647;
	static const int INF=4557430888798830399;
	static const int mod=1e9+7;
	static const int bas=131;
	
	int n,m,t;
	int num[MAX][MAX],sum[MAX][MAX];
	int vis[MAX*MAX][MAX][MAX][MAX][MAX];
	pair<int,int> ans,dp[MAX*MAX][MAX][MAX][MAX][MAX];
	
	pair<int,int> dfs(int T,int x,int y,int x_,int y_)
	{
		pair<int,int> &tmp=dp[T][x][y][x_][y_];
		if(vis[T][x][y][x_][y_]) return tmp;
		vis[T][x][y][x_][y_]=1;
		if(!T) return tmp=mp(sum[x_][y_]-sum[x-1][y_]-sum[x_][y-1]+sum[x-1][y-1],sum[x_][y_]-sum[x-1][y_]-sum[x_][y-1]+sum[x-1][y-1]);
		tmp=mp(-INF,INF);
		for(int k=0;k<T;++k)
			for(int i=x;i<x_;++i)
			{
				pair<int,int> L=dfs(k,x,y,i,y_),R=dfs(T-k-1,i+1,y,x_,y_);
				if(tmp.second-tmp.first>max(L.second,R.second)-min(L.first,R.first))
					tmp=mp(min(L.first,R.first),max(L.second,R.second));
			}
		for(int k=0;k<T;++k)
			for(int i=y;i<y_;++i)
			{
				pair<int,int> L=dfs(k,x,y,x_,i),R=dfs(T-k-1,x,i+1,x_,y_);
				if(tmp.second-tmp.first>max(L.second,R.second)-min(L.first,R.first))
					tmp=mp(min(L.first,R.first),max(L.second,R.second));
			}
		return tmp;
	}
	
	inline void lmy_forever()
	{
		n=read(),m=read(),t=read();
		for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) num[i][j]=read(),sum[i][j]=num[i][j]-sum[i-1][j-1]+sum[i][j-1]+sum[i-1][j];
		ans=dfs(t,1,1,n,m);
		write(ans.second-ans.first,'\n');
		return;
	}
}

bool Med;

signed main()
{
//	file();
	fprintf(stderr,"%.3lf MB\n",(&Med-&Mbe)/1048576.0);
	LgxTpre::lmy_forever();
	cerr<<1e3*clock()/CLOCKS_PER_SEC<<" ms\n";
	return (0-0);
}
posted @ 2023-04-16 12:20  LgxTpre  阅读(60)  评论(0)    收藏  举报