题解:P7311 [COCI2018-2019#2] Maja
Handezheng · · 题解
题解:P7311 [COCI2018-2019#2] Maja
题目传送门
更垃圾的阅读体验
题意
给定
其中,有
思路
应为
设循环节长度为三且三个点的权值分别为
若循环节长度为二,会有两种方案,平均权值分别为
能够发现,
循环节大于三时证明与其类似,这里不再赘述。
那我们便可以把
时间复杂度
DP过程
设
初始化
转移:
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,l,r) for(int i = l;i <= r;i++)
const int N = 1e6 + 50,M = 1e3 + 50;
const int INF = 0x3f3f3f3f3f3f3f3f,INT = 0x7fffffff;
const int mod = 1e9 + 7;
int n,m,stx,sty,q,ans=-INF;
int c[105][105],mx[105][105];
int f[3][105][105];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
memset(f,0xcf,sizeof f);
cin>>n>>m>>stx>>sty>>q;
F(i,1,n) F(j,1,m) cin>>c[i][j];
F(i,1,n) F(j,1,m) mx[i][j]=max(max(c[i-1][j],c[i+1][j]),max(c[i][j-1],c[i][j+1]))+c[i][j];
f[0][stx][sty]=0;
for(int k=1;k<=min(q/2,n*m);k++){
int t=k&1,l=t^1;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
f[t][i][j]=max(max(f[l][i-1][j],f[l][i+1][j]),max(f[l][i][j-1],f[l][i][j+1]))+c[i][j];
ans=max(ans,f[t][i][j]*2 + (q/2-k)*mx[i][j] - c[i][j]);
}
}
cout<<ans;
return 0;
}
——