CODE[VS] 1043 方格取数

本文介绍了一个经典的算法问题——方格取数的最大值求解。通过动态规划的方法,寻找两条路径使得从左上角到右下角的数字之和最大。详细解析了状态转移方程,并给出了完整的C++实现代码。

题目链接:

CODE[VS] 1043 方格取数

题目描述 Description

设有N * N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。某人从图的左上角的A 点出发,可以向下行走,也可以向右走,直到到达右下角的B点。在走过的路上,他可以取走方格中的数.此人从A点到B 点共走两次,试找出2条这样的路径,使得取得的数之和为最大。

思路:

跟传纸条是一个题,不过有了新的体会.

dp[x1][y1][x2][y2] = max:{dp[x1-1][y1][x2-1][y2],dp[x1-1][y1][x2][y2-1],dp[x1][y1-1][x2][y2-1],dp[x1][y1-1][x2][y2-1]} + a[x1][y1];

if(x1!=x2 && y1 != y2) dp[x1][y1][x2][y2] += a[x2][y2]; 
 
//这下清晰了吧....
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define LL long long
using namespace std;

const int N = 58;
int dp[N][N][N][N]; 
int a[N][N]; 

int main()
{
    int n;
    cin>>n;
    while(1)
    {
        int x, y, w;
        cin>>x>>y>>w;
        if(x+y+w == 0 ) break;
        a[x][y] = w;
    }

    for(int i = 1; i <= n; i++)
    for(int j = 1; j <= n; j++)
    for(int k = 1; k <= n; k++)
    for(int h = 1; h <= n; h++)
    {   
        dp[i][j][k][h] = max(dp[i-1][j][k-1][h], max(dp[i-1][j][k][h-1], max(dp[i][j-1][k-1][h], dp[i][j-1][k][h-1]))) + a[i][j];
        if(i!=k && j!= h) dp[i][j][k][h] += a[k][h];

    }
    printf("%d\n", dp[n][n][n][n]);  
    return 0;
}
### L型骨牌铺设方格 对于L型骨牌铺设方格的问题,可以将其视为一种特殊的多米诺骨牌覆盖问题。通常情况下,标准的2×1或多米诺骨牌覆盖问题是相对简单的组合计问题,而引入L型骨牌会增加复杂度。 #### 递推关系建立 考虑一个大小为\(m \times n\)的矩形区域,其中\(m, n ≥ 2\)。如果允许使用L型骨牌以及可能的标准2×1骨牌,则需要构建合适的递推公式来解决此问题。然而,在给定资料中并没有直接提到如何处理带有L型骨牌的情况[^3]。因此,这里尝试基于已有信息扩展思路: - 对于最简单的情形——即仅含直立或平放的2×1骨牌时,已经建立了有效的递推公式\[f(n)=f(n−1)+f(n−2)\][^3]。 - 当加入L型骨牌后,情况变得更加多样化。假设存在某些特定位置能够容纳L型骨牌而不影响其他部分,则这些特殊布局也应被计入总的排列方式之中。 为了简化讨论并保持逻辑清晰,下面只针对宽度固定为2(即2xn)的情况下探讨解决方案,并假设有足够的空间让至少一对L型骨牌参与进来形成闭合路径或其他有效配置。 #### 动态规划求解策略 采用动态规划的思想,定义状态转移函如下: 设`dp[i]`代表长度为i时的不同合法铺设方案总; 则除了继承自传统两块砖头模式下的贡献外(`dp[i]=dp[i-1]+dp[i-2]`), 还需额外加上因新增加了L型组件所带来的可能性变化量Δ(i),具体决于当前索引值及其前后关联性。 由于涉及到更复杂的几何形状匹配过程,实际编程实现上可能会比较棘手,尤其是当试图枚举所有潜在的有效L型拼接形态时。不过理论上讲,只要能穷尽所有合理的放置选项并将它们映射到相应的子问题规模上去,就能通过累加的方式更新最终的结果集。 ```cpp // C++ code snippet demonstrating the concept of adding L-shaped tiles into consideration. #include <iostream> using namespace std; long long dp[1005]; // Assuming maximum value for 'n' does not exceed 1004. void initDP(){ dp[0] = 1; dp[1] = 1; dp[2] = 2; for (int i = 3; i <= 1004 ; ++i){ dp[i] = dp[i-1] + dp[i-2]; // Add contribution from possible placements of L-tiles here... // This part requires careful geometric analysis and may vary based on exact problem constraints. // For demonstration purposes only, this placeholder represents where you would add logic to account for L-shape contributions. // In practice, determining Δ(i) involves checking whether an L can fit at position i given previous states. } } int main() { int N; cin >> N; initDP(); cout << dp[N]<< endl; } ``` 上述代码片段展示了如何初始化基本的状态组,并预留了一个占位符用于后续添加有关L型骨牌的具体计算逻辑。需要注意的是,这部分具体的增量计算依赖于详细的几何分析,这超出了现有参考资料所提供的范围。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值