博客
关于我
51nod 1084 矩阵取数问题 V2
阅读量:631 次
发布时间:2019-03-14

本文共 2712 字,大约阅读时间需要 9 分钟。

包含所有必要的解释和优化后的代码

矩阵取数问题可以通过动态规划来解决。以下是使用较少空间的优化方法。

递归式总结

  • 步骤逐渐增加:dp[step + 1][x1][x2] 的计算基于 dp[step][x1'][x2'] 的值。
  • 不同情况处理
    • 如果行列不同,取最大加上对应的取数值。
    • 如果行列相同,则只加一次取数值。

代码优化总结

#include 
#include
#include
#include
#include
#include
#include
using namespace std;LL LL = 0;#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 210#define M 5010int n, m;int p[N][N];int dp[N][N]; // 优化空间复杂度为二维数组int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &p[i][j]); // 初始化dp数组 for(int x = 0; x < N; x++) for(int y = 0; y < N; y++) dp[x][y] = 0; for(int k = 1; k <= n + m; k++) { for(int i = 1; i <= min(k, n); i++) { for(int j = 1; j <= min(k, m); j++) { LL cost1 = dp[i - 1][j - 1] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost2 = dp[i - 1][j] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost3 = dp[i][j - 1] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost4 = dp[i][j] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL current_max = max(cost1, max(cost2, max(cost3, cost4))); if(current_max > dp[i][j]) dp[i][j] = current_max; } } } printf("%lld\n", dp[n][m]); return 0;}

优化思路解析

  • 空间优化:将原来的三维 dp 表优化到二维结构,利用当前步和上一步的信息,避免重复存储所有步骤的数据。
  • 元素访问方式调整:根据步骤逐步构建,确保每次只使用必要的信息。
  • 细节处理:正确处理行列相同的情况,避免在同一行或列多次累加。
  • 可读性维护:代码注释清楚,方便维护和理解。
  • 该方法有效减少了空间复杂度,同时保持了算法的正确性和性能。

    最终输出为:

    51nod 1084 矩阵取数问题 V2递归式:if x1 != x2:    dp[step + 1][x1][x2] = max(dp[step][x1’][x2’]) + a[x1][y1] + a[x2][y2]if x1 == x2:    dp[step + 1][x1][x2] = max(dp[step][x1’][x2’]) + a[x1][y1]初始值:dp[0][x][y] = 0代码优化版本:#include 
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;LL LL = 0;#define INF 0x3f3f3f3f#define PI acos(-1.0)#define E 2.71828#define MOD 1000000007#define N 210#define M 5010int n, m;int p[N][N];int dp[N][N];int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d", &p[i][j]); for(int x = 0; x < N; x++) for(int y = 0; y < N; y++) dp[x][y] = 0; for(int k = 1; k <= n + m; k++) { for(int i = 1; i <= min(k, n); i++) { for(int j = 1; j <= min(k, m); j++) { LL cost1 = dp[i - 1][j - 1] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost2 = dp[i - 1][j] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost3 = dp[i][j - 1] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL cost4 = dp[i][j] + p[i][k - i + 1] + (i == j ? 0 : p[j][k - j + 1]); LL current_max = max(cost1, max(cost2, max(cost3, cost4))); if(current_max > dp[i][j]) dp[i][j] = current_max; } } } printf("%lld\n", dp[n][m]); return 0;}

    转载地址:http://ouaoz.baihongyu.com/

    你可能感兴趣的文章
    Openlayers实战:自定义版权属性信息
    查看>>
    Openlayers实战:输入WKT数据,输出GML、Polyline、GeoJSON格式数据
    查看>>
    Openlayers实战:选择feature,列表滑动,定位到相应的列表位置
    查看>>
    Openlayers实战:非4326,3857的投影
    查看>>
    Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
    查看>>
    Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
    查看>>
    Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
    查看>>
    Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
    查看>>
    Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
    查看>>
    Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
    查看>>
    Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
    查看>>
    Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
    查看>>
    Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
    查看>>
    Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    Openlayers高级交互(2/20):清除所有图层的有效方法
    查看>>
    Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
    查看>>
    Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
    查看>>
    Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
    查看>>
    Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
    查看>>