大卫的密码
题意:
给定nxm矩阵,从(s,1)出发到(t,m)。
每次可以向下或向右移动一格
到达最后一行后可以继续向下并到达第一行(环形)
求路径权值最大和
思路:
对于任意一个位置,显然由于环形条件存在,其可由左 + 上 +(下+上)转移
并且无法返回前一列。
因此按列进行dp
记dp[i][j]:到达(i,j)得到的路径权值最大和
发现只有第一列的dp值确定
其他列依赖于第一列
对于(i,j)(j>1)
需dp确定其下面权值和的最大值X,答案为X+上面的权值和
需dp确定其上面权值和的最大值Y,答案为Y
dp[i][j]=max(X,Y)
nt n,m,s,t;
int a[2005][2005];
int f[2005][2005];
void solve(){
cin>>n>>m>>s>>t;
rep(i,1,n){
rep(j,1,m){
cin>>a[i][j];
}
}
memset(f,-inf,sizeof f);
f[s][1]=a[s][1];
rep(j,1,m){
vector<int>pre(n+1);
vector<int>suf(n+2);
vector<int>mxpre(n+1,-inf);
vector<int>mxsuf(n+2,-inf);
rep(i,1,n)pre[i]=pre[i-1]+a[i][j];
for(int i=n;i>=1;i--)suf[i]=suf[i+1]+a[i][j];
for(int i=n;i>=1;i--)mxsuf[i]=max(mxsuf[i+1],f[i][j-1]+suf[i]);
rep(i,1,n)mxpre[i]=max(mxpre[i-1]+a[i][j],f[i][j-1]+a[i][j]);
if(j==1){
for(int i=1;i<s;i++){
f[i][j]=suf[s]+pre[i];
}
for(int i=s+1;i<=n;i++){
f[i][j]=pre[i]-pre[s-1];
}
}else{
for(int i=1;i<=n;i++){
f[i][j]=max(mxsuf[i+1]+pre[i],mxpre[i]);
}
}
}
cout<<f[t][m]<<endl;
}

浙公网安备 33010602011771号