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;
}
双线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;
}
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- LFC1.0.0 版本发布
- ACM程序设计大赛题目分类
- Android dpi,dip,dp的概念以及屏幕适配
- 计算字符串最后一个单词长度
- Android px、dp、sp之间相互转换
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- 矩阵的乘法操作
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法