题目大意:
有一个$n\times m(x,m\leq 100)$的网格图,每个格子有一个权值$w_{i,j}(1\leq w_{i,j}\leq 9)$。你可以在图中选两个格子,每个格子$(x,y)$可以接收$k(k\leq 10)$个格子,$(x+dx[1],y+dy[1]),(x+dx[2],y+dy[2]),\ldots,(x+dx[k],y+dy[k])$的权值。超出边界的能量不接收,每个格子的权值最多被接收一次,问最多能接收多少权值。思路:
考虑选择不同格子,吸收权值的范围不相交的情况,我们可以直接暴力$O(nmk)$求出每个点能吸收的权值,然后选两个最大的加起来即可。 现在每个格子的吸收范围可能会相交,因此我们还需要分两种情况考虑。 我们可以先求出每个点能吸收的权值,然后找出吸收范围会和该点重合的点,不难发现这样的点最多只有$k^2$个。 对于会相交的点,我们暴力求一下可以吸收哪些点的权值,对于不相交的点,可以直接用稀疏表求区间最大值,时间复杂度$O(nmk^2\log(nm))$。1 #include2 #include 3 #include 4 #include 5 inline int getint() { 6 register char ch; 7 register bool neg=false; 8 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 9 register int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return neg?-x:x; 12 } 13 inline int getblock() { 14 register char ch; 15 while(!isdigit(ch=getchar())); 16 return ch^'0'; 17 } 18 typedef std::pair Point; 19 const int N=100,K=10,logN2=15; 20 std::set set; 21 bool vis[N*N],b[N][N]; 22 int n,m,k,a[N][N],dx[K],dy[K],max[N*N][logN2],q[K*K+3]; 23 inline bool check(const int &x,const int &y) { 24 return x>=0&&x =0&&y >23&255)-127; 31 } 32 inline int query(const int &l,const int &r) { 33 const int k=log2(r-l+1); 34 return std::max(max[l][k],max[r-(1<