洛谷1387的进阶版,但很像。

1387要求是“全为1的正方形”,取dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1]))吧?这个有“只有对角线可以有1”的要求,取的是dp[i][j] = min(dp[i-1][j-1], min(s1[i-1][j], s2[i][j-1])),s1s2是预处理的两个数组,表示上方和左方有多少连续的0.另外本题左右方向对角线都算,所以得算两遍。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
int n, m, ans, a[maxn][maxn];
int s1[maxn][maxn], s2[maxn][maxn], dp[maxn][maxn]; int main() {
scanf("%d %d", &n, &m);
for (int i = ; i <= n; i++) {
for (int j = ; j <= m; j++) {
scanf("%d", &a[i][j]);
}
} for (int i = ; i <= n; i++) {
for (int j = ; j <= m; j++) {
if (!a[i][j]) {
s1[i][j] = s1[i-][j] + ;//up
s2[i][j] = s2[i][j-] + ;//left
} else {
dp[i][j] = min(dp[i-][j-], min(s1[i-][j], s2[i][j-])) + ;
ans = max(ans, dp[i][j]);
}
}
}
memset(dp, , sizeof dp);
memset(s2, , sizeof s2);
for (int i = ; i <= n; i++) {
for (int j = m; j; j--) {
if (!a[i][j]) s2[i][j] = s2[i][j+] + ;//right
else {
dp[i][j] = min(dp[i-][j+], min(s1[i-][j], s2[i][j+])) + ;
ans = max(ans, dp[i][j]);
}
}
} printf("%d\n", ans);
return ;
}

而我自己做时……我这种满脑子二分前缀和的暴力分子大概没救了吧~不过这两种做法时间和空间上相差不多,反而是暴力快一点(逃

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int n, m, ans;
int a[][], b[][], sum1[][], sum2[][], dp[][]; void DP(int a[][], int sum[][]) {
for (int i = ; i <= n; i++) {
for (int j = ; j <= m; j++) {
if (a[i][j]) {
auto ok = [](int i, int j, int tmp, int sum[][]) {
return sum[i][j] - sum[i - tmp][j] - sum[i][j - tmp] + sum[i - tmp][j - tmp] == tmp;
};
int l = , r = dp[(i - )&][j - ] + , t;
while (l <= r) {
int mid = (l + r) >> ;
if (ok(i, j, mid, sum)) {
t = mid;
l = mid + ;
} else r = mid - ;
}
dp[i&][j] = t;
} else dp[i&][j] = ;
ans = max(ans, dp[i&][j]);
}
}
} int main() {
scanf("%d %d", &n, &m);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
scanf("%d", &a[i][j]);
b[i][m - j + ] = a[i][j];
}
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
sum1[i][j] = sum1[i - ][j] + sum1[i][j - ] - sum1[i - ][j - ] + a[i][j];
sum2[i][j] = sum2[i - ][j] + sum2[i][j - ] - sum2[i - ][j - ] + b[i][j];
}
DP(a, sum1);
memset(dp, , sizeof dp);
DP(b, sum2);
printf("%d\n", ans);
return ;
}

洛谷1736(二维dp+预处理)的更多相关文章

  1. 传纸条 NOIP2008 洛谷1006 二维dp

    二维dp 扯淡 一道比较基本的入门难度的二维dp,类似于那道方格取数,不过走过一次的点下次不能再走(看提交记录里面好像走过一次的加一次a[i][j]的也AC了,,),我记得当年那道方格取数死活听不懂, ...

  2. 洛谷1387 二维dp 不是特别简略的题解 智商题

    洛谷1387 dp题目,刚开始写的时候使用了前缀和加搜索,复杂度大概在O(n ^ 3)级别,感觉这么写还是比较对得起普及/提高-的难度的..后来看了题解区各位大神的题解,开始一脸mb,之后备受启发. ...

  3. 洛谷p1732 活蹦乱跳的香穗子 二维DP

    今天不BB了,直接帖原题吧  地址>>https://www.luogu.org/problem/show?pid=1732<< 题目描述 香穗子在田野上调蘑菇!她跳啊跳,发现 ...

  4. 洛谷P1048 采药 二维dp化一维

    题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个 ...

  5. 洛谷P1140 相似基因 (DP)

    洛谷P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. ...

  6. 洛谷 P2015 二叉苹果树 (树上背包)

    洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...

  7. HDU - 2159 FATE(二维dp之01背包问题)

    题目: ​ 思路: 二维dp,完全背包,状态转移方程dp[i][z] = max(dp[i][z], dp[i-1][z-a[j]]+b[j]),dp[i][z]表示在杀i个怪,消耗z个容忍度的情况下 ...

  8. 关于二维DP————站上巨人的肩膀

    意匠惨淡经营中ing, 语不惊人死不休........ 前几天学了DP,做了个简单的整理,记录了关于DP的一些概念之类的,今天记录一下刚学的一个类型 ----关于二维DP 那建立二维数组主要是干嘛用的 ...

  9. 洛谷1387(基础二维dp)

    题目很简单,数据也很小,但是思路不妨借鉴:dp[i][j]代表以(i,j)为右下角的最长正方形边长. 类比一维里面设“以XX为结尾的最XXX(所求)”. 另外define不要乱用!尤其这种min套mi ...

随机推荐

  1. 一个动态库连续注册的windows脚本regsvr32

    cmd ->for %1 in (%windir%\system32\*.dll) do regsvr32.exe /s %1

  2. TreeSet实现Comparator接口的排序算法的分析

    为了方便,用lambda表达式代替comparator接口 例子如下: public static void main(String[] args) { TreeSet<Integer> ...

  3. bash的pushd和popd

    1 pushd和popd是bash shell的builtin命令 2 pushd和popd维护了一个目录栈 pushd xxx就是将xxx放入目录栈顶. 目录栈顶就是当前的目录. 但是cd的话,会不 ...

  4. Writing a Simple YARN Application 从hadoop生态抽出yarn ,单独使用yarn

    Apache Hadoop 2.9.1 – Hadoop: Writing YARN Applications https://hadoop.apache.org/docs/current/hadoo ...

  5. FMDB 使用技巧

    源链接:  http://blog.csdn.net/iunion/article/details/7091744 - (BOOL) isTableOK:(NSString *)tableName{  ...

  6. 多线程、死锁、线程安全、同步方法、代码块、休眠、守护线程、Thread、Runnable(二十三)

    1.多线程的引入 * 1.什么是线程 * 线程是程序执行的一条路径, 一个进程中可以包含多条线程 * 多线程并发执行可以提高程序的效率, 可以同时完成多项工作* 2.多线程的应用场景 * 红蜘蛛同时共 ...

  7. jquery 获取radio被选中的值

    <html> <head> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"& ...

  8. COGS-2049 疯狂动物城

    Description 你意外来到了一个未知的星球, 这里是一个动物乌托邦, 生活着一群拥有非凡智力的动物. 你遇到了一个叫做尼克的狐狸, 他准备给他的 GF 过生日 . 他将制作一个巨大的多层蛋糕, ...

  9. BZOJ_4278_[ONTAK2015]Tasowanie_后缀数组

    BZOJ_4278_[ONTAK2015]Tasowanie_后缀数组 Description 给定两个数字串A和B,通过将A和B进行二路归并得到一个新的数字串T,请找到字典序最小的T. Input ...

  10. bzoj2973石头游戏——矩阵乘法

    题目:权限题! 写了一下,但提交不了,先放着吧. 代码如下: #include<iostream> #include<cstdio> #include<cstring&g ...