CF 429B B.Working out (四角dp)

题意:

两个人一个从左上角一个从左下角分别开始走分别走向右下角和右上角,(矩阵每个格子有数)问到达终点后可以得到的最大数是多少,并且条件是他们两个相遇的时候那个点的数不能算

思路:

首先这道题如果暴力搜索一般是gg了,所以考虑动态规划

我们设起点为st(1,1),终点为ed(n,m),相遇的点为now(i,j)
问题转化为计算st→now + now→ed的值(不包含now)

这个问题可以分解为求st→nownow→ed的值,st→now = dp[st][now],那么now→ed怎么求呢
可以反过来思考,now→ed其实就是ed→now的值,反向dp即可

还有个很重要的问题
在相遇的时候,即在点now时,每条路径只能走相对的边,如图

如果走的是临边,效果可能不一样,可以试试。。。

代码:

#include<iostream>
#include<cstring>
#define max(a, b) ((a)>(b)?(a):(b))
using namespace std;
typedef long long ll;
const int maxn = 1010;
int mp[maxn][maxn];
int dp1[maxn][maxn],dp2[maxn][maxn],dp3[maxn][maxn],dp4[maxn][maxn];
int main() {
    memset(dp1, 0, sizeof dp1);
    memset(dp2, 0, sizeof dp2);
    memset(dp3, 0, sizeof dp3);
    memset(dp4, 0, sizeof dp4);
    int n,m;
    scanf("%d %d", &n,&m);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            scanf("%d", &mp[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]) + mp[i][j];//到点(i,j)有两种方法,以下如此
        }
    }
    //从左上 走
    for(int i = n; i >= 1; i--) {
        for(int j = m; j >= 1; j--) {
            dp2[i][j] = max(dp2[i+1][j], dp2[i][j+1]) + mp[i][j];
        }
    }
    //从右上 走
    for(int i = n; i >= 1; i--) {
        for(int j = 1; j <= m; j++) {
            dp3[i][j] = max(dp3[i+1][j], dp3[i][j-1]) + mp[i][j];
        }
    }
    //从左下 走
    for(int i = 1; i <= n; i++) {
        for(int j = m; j >= 1; j--) {
            dp4[i][j] = max(dp4[i-1][j], dp4[i][j+1]) + mp[i][j];
        }
    }

    ll ans = -1;
    for(int i = 2; i < n; i++) {
        for(int j = 2; j < m; j++) {
            ans = max(dp1[i-1][j] + dp2[i+1][j] + dp3[i][j-1] + dp4[i][j+1], ans);
            ans = max(dp1[i][j-1] + dp2[i][j+1] + dp3[i+1][j] + dp4[i-1][j], ans);
                        //把横向穿过和纵向穿过,两者进行枚举
        }
    }
    printf("%d\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/somliy/p/9719540.html

时间: 2024-11-08 09:56:57

CF 429B B.Working out (四角dp)的相关文章

CF 366C Dima and Salad [天平DP]

题目大意:n个水果,水果有甜度和卡路里两个属性,选择一些水果,使得甜度之和与卡路里之和比例为k,并且使得甜度之和最大 我们可以定义二维dp,dp[当前游标扫到的个数][平衡度]=当前平衡度下最大的ai和,平衡度定义为ai-bi*k,很巧秒的定义方式,可以节省一维时空. 注意到平衡度可正可负(范围在-10000到10000) 我们可以定义如下 int m[1111][22222] int *d[i]=&m[i][10000] dp[num+1][balance]=max(self,dp[num][

CF #374 (Div. 2) C. Journey dp

1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径,经过的点数要最多. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,

CF 372B Counting Rectangles is Fun [dp+数据维护]

题意,给出一个n行m列的矩阵 里面元素是0或者1 给出q个询问 a,b,c,d 求(a,b)到(c,d)有多少个由0组成的矩形 我们定义 即为求(a,b)到(c,d)有多少个由0组成的矩形 对一个矩形来说 dp[a][b][c][d]=dp[a][b][c][d-1]+dp[a][b][c-1][d]-dp[a][b][c-1][d-1]+包含右下角(当前点)的矩形; 重点就在包含右下角(当前点c,d)的矩形,如何计算这个 我们可以暴力扫描,需要nm的复杂度,乘上原有复杂度,,,已经会超过时限

CF EDU 1101D GCD Counting 树形DP + 质因子分解

CF EDU 1101D GCD Counting 题意 有一颗树,每个节点有一个值,问树上最长链的长度,要求链上的每个节点的GCD值大于1. 思路 由于每个数的质因子很少,题目的数据200000<2*3*5*7*11*13*17=510510.所以每个节点的质因子个数不多.那么树形DP的时候直接枚举每种因子即可. //#pragma GCC optimize(3) //#pragma comment(linker, "/STACK:102400000,102400000") /

CF 337D Book of Evil 树形DP 好题

Paladin Manao caught the trail of the ancient Book of Evil in a swampy area. This area contains n settlements numbered from 1 to n. Moving through the swamp is very difficult, so people tramped exactly n - 1 paths. Each of these paths connects some p

CF 2B The least round way DP+Math

题意: 找出一条路, 使每个节点相乘,得到的数末尾 0 最少 每次移动只能向右或者向下, 找到后打印路径 ///按照题目要求,就是找出一条从左上角到右下角中每个数含2 or 5 最少的路 ///可以用Dp的思想, 然后把每个节点该走的方向记下来 ///再从终点回溯,把路径存入栈,再输出 ///数据会有0的情况, 这时候我们应该记录离终点最近的0 #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef

CF 148d Bag of mice 概率DP 好题

D. Bag of mice The dragon and the princess are arguing about what to do on the New Year's Eve. The dragon suggests flying to the mountains to watch fairies dancing in the moonlight, while the princess thinks they should just go to bed early. They are

CF 258B Little Elephant and Elections [dp+组合]

给出1,2,3...m 任取7个互不相同的数a1,a2,a3,a4,a5,a6,a7 一个数的幸运度是数位上4或7的个数 比如244,470幸运度是2. 44434,7276727,4747,7474,幸运度都是4. 求出满足a1,a2,a3,a4,a5,a6,a7这样的前6个数的幸运度之和严格小于第七个数的幸运度排列共有多少种 1.先求出数组t t[i]代表1-m中幸运度为i的数的个数. 2.有了t数组后,问题变为一个排列组合问题(枚举a7幸运度,求有多少排列满足前6幸运度之和小于a7幸运度,

CF 55D Beautiful numbers (数位DP)

题意: 如果一个正整数能被其所有位上的数字整除,则称其为Beautiful number,问区间[L,R]共有多少个Beautiful number?(1<=L<=R<=9*1018) 思路: 数字很大,不能暴力.但是想要知道一个数是否为Beautiful number时,至少得等到它的所有位都出现吧?不然如何确定其实可以被整除的呢? 分析一下,类似2232和3232等这样的数字,这两个只是出现了2和3而已,他们的lcm都是6,所以有可以压缩统计的地方就是lcm,开一维来存储.接下来考虑