1.题目描述:点击打开链接
2.解题思路:本题属于棋盘型dp问题。根据题意,我们需要完整的描述一个矩形,以便于进行状态的转移,可以用(r,c,w,h)来描述一个矩形,(r,c)是矩形的左上角坐标。w是矩形的宽,h是矩形的高。那么不难得到如下的两个状态转移方程:
(横切)
dp(r,c,w,h)=max{dp(r,c,w,h),w+dp(r,c,w,i)+dp(r+i,c,w,h-i)}(1<=i<=h);
(竖切)
dp(r,c,w,h)=max{dp(r,c,w,h),h+dp(r,c,i,h)+dp(r,c+i,w-i,h)}(1<=i<=w);
上述方程描述的是横切和竖切两种情况,可以利用记忆化搜索计算。不过根据题意,需要保证切出来的两个矩形都含有一个樱桃。可以事先递推计算从(r,c)到右下角这个矩形的总的樱桃个数。不妨用val数组表示,则有:
val(r,c)=val(r,c)+val(r+1,c)+val(r,c+1)-val(r+1,c+1)+g[r][c];
那么计算矩形(r,c)~(r+h,c+w)内部的樱桃个数就是:val(r,c)-val(r+h,c)-val(r,c+w)+val(r+h,c+w)。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#