您的位置:首页 > 其它

NYOJ 61 传纸条(一)

2016-05-18 09:08 218 查看
点击打开题目链接

双线dp,dp[sum][x1][x2] 表示两个纸条传递到位置(x1,y1)、(x2,y2)所获得的最大好心程度和

其中 sum = x1 + y1 = x2 + y2,sum记录横纵坐标和

这样就优化到了三维

同单线dp有点相似,只是此处两条路径不能相交,我们在状态转移的时候让 x1 != x2

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int maxn = 50 + 5;
int dp[2 * maxn][maxn][maxn];
int num[maxn][maxn];

int main()
{
int T, n, m;
scanf("%d", &T);
while (T--)
{
memset(dp, 0, sizeof(dp));
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &num[i][j]);

for (int sum = 3; sum < n + m; sum++)
{
for (int x1 = 1; x1 <= n; x1++) //第一条路的横坐标
{
for (int x2 = x1 + 1; x2 <= n; x2++) //第两条比第一条的横坐标大 ,不让它们相交
{
if (sum - x1 < 1 || sum - x2 < 1) break; //由x+y=sum知 y=sum-x 此处控制y的范围,下同
if (sum - x1 > m || sum - x2 > m) continue;
//状态转移,有四种状态可以转移到当前状态 ,取最大值并加上当前位置的值
dp[sum][x1][x2] = num[x1][sum - x1] + num[x2][sum - x2]
+ max(max(dp[sum - 1][x1][x2], dp[sum - 1][x1 - 1][x2 - 1]),
max(dp[sum - 1][x1 - 1][x2], dp[sum - 1][x1][x2 - 1]));
}
}
}
int t = n + m; //最终结果一定是一个向下走,一个向右走
dp[t]

= max(dp[t - 1]
[n - 1], dp[t - 1][n - 1]
);
printf("%d\n", dp[t]

);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm dp