2020CSP-J普及组复赛 D.方格取数(number)(简单dp)

LINK


容易想到定义 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i列处于位置 j j j的花费

定义 W ( i , j , q ) W(i,j,q) W(i,j,q)表示第 i i i列第 m i n ( j , q ) min(j,q) min(j,q)行到第 m a x ( j , q ) max(j,q) max(j,q)行的权值

那么枚举状态 O ( n m ) O(nm) O(nm),转移枚举一个 q q q得到

f [ i ] [ j ] = m a x { f [ i − 1 ] [ q ] + W ( i , j , q ) } \rm f[i][j]=max\{f[i-1][q]+W(i,j,q)\} f[i][j]=max{f[i1][q]+W(i,j,q)}

复杂度 O ( n 3 ) O(n^3) O(n3)

考虑 f [ i ] [ j ] f[i][j] f[i][j] f [ i − 1 ] [ q ] f[i-1][q] f[i1][q]转移当 q < = j q<=j q<=j

维护一个 m x mx mx值表示当 q ∈ [ 1 , j − 1 ] q\in[1,j-1] q[1,j1]时最优的 f [ i − 1 ] [ q ] + W ( i , q , j − 1 ) f[i-1][q]+W(i,q,j-1) f[i1][q]+W(i,q,j1)

那么现在走到第 j j j行还需要往下走一格,也就是更新一个 m a x max max即可

m x = m a x ( f [ i − 1 ] [ j ] , m x ) + a [ j ] [ i ] \rm mx=max(f[i-1][j],mx)+a[j][i] mx=max(f[i1][j],mx)+a[j][i]

为了考虑 q > j q>j q>j的情况,倒序再做一遍

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1009;
const int inf = 0x3f3f3f3f;
int n,m,a[maxn][maxn],pre[maxn][maxn],f[maxn][maxn];
inline int max(int a,int b){ return a>b?a:b; }
inline void r(int& a) 
{
    char c = getchar(); bool f = 1;
    for(;c<'0' || c>'9';c = getchar()) if (c=='-') f = 0;
    for(;c>='0' && c<='9';a = (a+(a<<2)<<1)+(c&15),c = getchar());
    if(!f) a = ~(a-1);
}
signed main()
{
	r( n ); r( m );
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		r( a[i][j] );
		pre[i][j] = pre[i-1][j]+a[i][j];
	}
	for(int j=1;j<=n;j++)	f[1][j] = pre[j][1];
/*
f[i][j]由f[i-1][q]转移而来
当q<=j时,随着j的增大,所有f[i-1][0..j]只是增大了一个a[i-1][q]而已 
*/ 
	for(int i=2;i<=m;i++)//前m列 
	{
		int mx = -inf;
		for(int j=1;j<=n;j++)//当前在位置j 
		{
			mx = max( mx+a[j][i],f[i-1][j]+a[j][i] );
			f[i][j] = mx;
		}
		mx = -inf;
		for(int j=n;j>=1;j--)//当前在位置j 
		{
			mx = max( mx+a[j][i],f[i-1][j]+a[j][i] );
			f[i][j] = max( f[i][j],mx );
		}
	}
	cout << f[m][n];
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值