hdu1081To The Max(dp)
来源:互联网 发布:双防火墙网络环境搭建 编辑:程序博客网 时间:2024/06/04 00:49
题目请戳这里
题目大意:给一个n*n的矩阵,矩阵每个元素为一个整数,求权值和最大的子矩阵。
题目分析:这是求最大连续子序列和的二维版本。所以我们可以先看看一维情况:求一个序列的最大连续子序列和。
很显然可以朴素O(n^2)解决这个问题,但是如果我们利用前缀和的话,可以做到O(n)。dp[i]表示前i个数最大连续子序列。那么有方程:dp[i] = max(dp[i - 1] + a[i],a[i])。即要么这个最大连续子序列包含a[i]或者不包含a[i]。
然后再回到二维情况:很显然可以朴素O(n^4)解决这个问题。枚举矩阵的所有子矩阵就可以了。不过这样时空复杂度太高,不妨参照一维情况优化:枚举前i行,dp[i][j][k]表示前i行从第j列到第k列最大子矩阵。那么显然有dp[i][j][k] = max(dp[i - 1][j][k] + a[i][k] - a[i][j - 1],a[i][k] - a[i][j - 1]),其中a[i][j]表示原矩阵中第i行前j列和。这样问题就可以O(n^3)时间解决了。
再仔细看看转移方程,不难发现其实dp数组还可以省掉一维,因为每个dp[i][j][k]只需要知道dp[i - 1][j][k]就可以了,所以dp数组第一维可以去掉。
详情请见代码:
#include <iostream>#include<cstdio>#include<cstring>using namespace std;const int N = 101;int lcm[N][N],dp[N][N][N];int n;int main(){ int i,j,k; while(scanf("%d",&n) != EOF) { memset(dp,0,sizeof(dp)); memset(lcm,0,sizeof(lcm)); for(i = 1;i <= n;i ++) for(j = 1;j <= n;j ++) scanf("%d",&lcm[i][j]),lcm[i][j] += lcm[i][j - 1]; int ans = -100000; for(i = 1;i <= n;i ++) { for(j = 1;j <= n;j ++) { for(k = j;k <= n;k ++) { dp[i][j][k] = max(lcm[i][k] - lcm[i][j - 1],lcm[i][k] - lcm[i][j - 1] + dp[i - 1][j][k]); ans = max(dp[i][j][k],ans); } } } printf("%d\n",ans); } return 0;}
0 0
- hdu1081To The Max(dp)
- hdu1081To The Max
- hdu1081To The Max【动态规划】
- 【动态规划】HDU1081To The Max
- hdu1081To The Max(动态规划--初步)
- DP:HDU_1081_To The Max
- To the Max (DP)
- DP::Poj1050 To the max
- poj1050 To the Max (dp)
- POJ1050 TO THE MAX [DP]
- 1050 To the Max DP
- poj1050 to the max (DP)
- poj1050 To the Max dp
- hdu1081 To The Max (dp)
- To The Max(dp思想)
- pku1050 To the Max DP
- HDU1081 To The Max (DP)
- poj1050 To the Max dp
- C#之"0x{0:x}"
- UVa:11076 Add Again
- java设计模式1——工厂方法模式(Factory Method)
- JavaScript与Java的区别:
- POJ1555解题报告
- hdu1081To The Max(dp)
- hdu 1394 树状数组
- 插APC实现DLL注入
- (十四)矩阵类与对称矩阵的压缩算法
- 温州企业家苦干1年挣百万 妻子炒房8年赚3000万
- 又一版 A+B 浙大计算机研究生复试上机考试-2008年
- 基础背包问题的一些题目!!
- struts2 标签自动提示
- 开始在CSDN上安家了哈!