Codeforces Round #245 (Div. 1) B. Working out

本文探讨了两人从网格的对角线两端走向另一对角线端点,路径仅允许一次交叉的情况下,如何利用动态规划求得两人能获取的最大路径值。文章详细解析了DP状态转移方程,并通过枚举交点位置来解决复杂问题。

题目大意:

有一个人从左上角走到右下角,有一个人从左下角走到右上角。

两个人的路线只能有一个交点。每一个格子都有自己的值,走过这个路径就能获得对应的值。

规定两个人路线的交点的值两个人都不能获得。

求这两个人获得的值得最大值时多少

大致思路:

​ 首先先考虑简化的情况:只有一个人的时候,从左上走到右下角所能获得的最大值时多少?

​ 这个问题很显然的可以用DP去求,转移方程为:

\(dp[i][j] = max(dp[i-1][j],dp[i][j-1]) +g[i][j]\)

其中 \(g[i][j]\) 表示的是这个格子的值,\(dp[i][j]\) 表示的是走到 \(i\) 行,\(j\) 列时所能获得的最大收益。

​ 现在把之前的问题进行拓展,变成有两个人的时候,两个人所能获得的最大值是多少。(不考虑路径相交)

这个问题的解也很简单,和上面的一样列一个式子就可以了,不过转移需要稍微变化一下:

\(dp[i][j] = max(dp[i+1][j],dp[i][j-1]) +g[i][j]\)

现在把问题再拓展成题目中要求的情况。对于这个交点我们可以做出推断:

1.两个路径的交点一定是一个十字形状,且每一个人只能走直线。通过画图很容易就能得到。

2.交点的坐标不可能在边界上,通过画图也能很轻松的看出来。

于是我们可以尝试着去枚举这个交点,复杂度是 \(O(n^2)\) 的,很OK。

那么对于这个交点,我们需要知道两个人从出发点到这个点的最大值和从这个点分别到右下角与右上角的距离。

对于第一个问题,我们已经通过之前的两个dp式子得到。对于第二个问题,我们可以把实际情况倒过来考虑:

从交点分别到右下角和右上角的距离

变成

分别从右下角和右上角到交点的距离

问题一下子变得熟悉多了,就是之前推出来的那两个式子的变形。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+7;
ll dp1[maxn][maxn],dp2[maxn][maxn],dp3[maxn][maxn],dp4[maxn][maxn];
int g[maxn][maxn];
int main()
{
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n,m;
    ll ans=0;
    cin>>n>>m;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            cin>>g[i][j];
    //左上
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1])+g[i][j];
    //左下
    for(int i=n;i>=1;--i)
        for(int j=1;j<=m;++j)
            dp2[i][j]=max(dp2[i+1][j],dp2[i][j-1])+g[i][j];
    //右上
    for(int i=1;i<=n;++i)
        for(int j=m;j>=1;--j)
            dp3[i][j]=max(dp3[i-1][j],dp3[i][j+1])+g[i][j];
    //右下
    for(int i=n;i>=1;--i)
        for(int j=m;j>=1;--j)
            dp4[i][j]=max(dp4[i+1][j],dp4[i][j+1])+g[i][j];
    for(int i=2;i<n;++i)
        for(int j=2;j<m;++j){//两种交叉情况,用笔画一画就明白了
            ll p1=dp1[i-1][j]+dp4[i+1][j];
            ll p2=dp2[i][j-1]+dp3[i][j+1];
            ans=max(ans,p1+p2);
            //cout<<"1 "<<i<<" "<<j<<" "<<p1<<" "<<p2<<endl;
            p1=dp1[i][j-1]+dp4[i][j+1];
            p2=dp2[i+1][j]+dp3[i-1][j];
            ans=max(ans,p1+p2);
           // cout<<"2 "<<i<<" "<<j<<" "<<p1<<" "<<p2<<endl;
        }
    cout<<ans<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/SCaryon/p/9152703.html

Delphi 12.3 作为一款面向 Windows 平台的集成开发环境,由 Embarcadero Technologies 负责其持续演进。该环境以 Object Pascal 语言为核心,并依托 Visual Component Library(VCL)框架,广泛应用于各类桌面软件、数据库系统及企业级解决方案的开发。在此生态中,Excel4Delphi 作为一个重要的社区开源项目,致力于搭建 Delphi 与 Microsoft Excel 之间的高效桥梁,使开发者能够在自研程序中直接调用 Excel 的文档处理、工作表管理、单元格操作及宏执行等功能。 该项目以库文件与组件包的形式提供,开发者将其集成至 Delphi 工程后,即可通过封装良好的接口实现对 Excel 的编程控制。具体功能涵盖创建与编辑工作簿、格式化单元格、批量导入导出数据,乃至执行内置公式与宏指令等高级操作。这一机制显著降低了在财务分析、报表自动生成、数据整理等场景中实现 Excel 功能集成的技术门槛,使开发者无需深入掌握 COM 编程或 Excel 底层 API 即可完成复杂任务。 使用 Excel4Delphi 需具备基础的 Delphi 编程知识,并对 Excel 对象模型有一定理解。实践中需注意不同 Excel 版本间的兼容性,并严格遵循项目文档进行环境配置与依赖部署。此外,操作过程中应遵循文件访问的最佳实践,例如确保目标文件未被独占锁定,并实施完整的异常处理机制,以防数据损毁或程序意外中断。 该项目的持续维护依赖于 Delphi 开发者社区的集体贡献,通过定期更新以适配新版开发环境与 Office 套件,并修复已发现的问题。对于需要深度融合 Excel 功能的 Delphi 应用而言,Excel4Delphi 提供了经过充分测试的可靠代码基础,使开发团队能更专注于业务逻辑与用户体验的优化,从而提升整体开发效率与软件质量。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值