PASCAL 最大子矩阵 时间复杂度o(nm) 神牛快来啊!!!
你也是够6的,一个ACM的题你能搞个4重循环,不超时才怪。
主要思想就是把2维德矩阵压缩为1维
然后把问题转化为:给你一个长度确定的序列,要你在这个序列里求一个权值最大的连续子区间
这个你会不?
也就是说,举个例子
1 -1 2 0 3 5 8
2 7 3 1 -9 -8 1
对于这个矩阵
我们求出的子矩阵只要求权值和最大,那么那个最优解必然是
第一排的连续K个数之和加第二排连续K个数之和
即a[1][i]+a[1][i+1]+....a[1][i+k] + a[2][i]+...a[2][i+k];
也等于 a[1][i]+a[2][i]+a[1][i+1]+a[2][i+1].....
也就是相当于如果把第二排和第一排相加,变成一排数,那么这一排数就是一个宽度为2的矩阵
那么问题就转化为在序列 C1,C2,C3...Cn中求出一个最大的连续子区间。,那么求出的这个区间还原的话就是一个K*2的矩阵。
通过这个方法,我们可以枚举所有的排数,即找一个起点排,找一个终点排,把这之间的的所有数压缩为一行,然后压缩后的序列用动态规划求一次最大连续子区间。
整个问题也就解决了
对于求最长连续子区间
我们设F[i]为序列C的前i个数,必须以i作为结尾的最长连续子区间。
因为是连续区间,所以说对于第i个数只有两种决策,要么和前面的数连在一起,要么自己作为开头。
那么F[I]=MAX(F[I-1]+C[I],C[I])
/*
ID: englanq1
PROG:
LANG: C++
*/
#include
#include
#include
using namespace std;
int map[200][200];
int f[200];
int n,ans;
int a[200];
void readdata()
{
scanf("%d
",&n);
int i,j;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
scanf("%d",&map[i][j]);
}
void work()
{
int i,j,q,tem,m,k;
for(i=1; i<=n; i++)
for(j=1; j<=n-i+1; j++)
{
for(q=1; q<=n; q++)
{
tem=0;
for(k=i; k<=i+j-1; k++)
tem+=map[k][q];
a[q]=tem;
}
for(q=0; q<=n; q++)
f[q]=0;
f[1]=a[1];
if(f[1]>ans) ans=f[1];
for(m=2; m<=n; m++)
{
f[m]=a[m]>f[m-1]+a[m] ? a[m]:f[m-1]+a[m];
if(f[m]>ans) ans=f[m];
}
}
}
void print()
{
printf("%d
",ans);
}
int main()
{
readdata();
work();
print();
return 0;
}
在高清度算法中,最大可达36579的100000000000000次方,后面有9个0
以岚立将: 简单的算法是枚举子矩形的左上角以及右下角坐标,然后再枚举计算矩形的大小,取最大值.总共6重循环,时间复杂度是原矩阵边长的6次方.Program ex;Vara: array [0..200, 0..200] of longint;n, m, x1, y1, x2, y2, i, j, sum, max: longint;...
道里区17686299008: PASCAL月饼盒(最大子矩阵),怎么做 - ?
以岚立将: 楼上的程序也太长了,五成会超时给你一个优化的vara:array[1..1000,1..1000]of longint;b:array[1..1000]of longint;i,j,m,n,i1,i2:longint;ans,max:int64;beginreadln(m,n);for i...
道里区17686299008: pascal程序1059: 【基础】隐藏的最大整数 时间限制: 1 Sec 内存限制: 16 MB 提交: 1092 解决: 547 [提交][ - ?
以岚立将: 我觉得你那样做有点烦,我是这样做的: var s:string; a:array[1..255,1..2] oflongint; n,i,j,k,l:longint; begin readln(s); k:=1; fori:=1tolength(s) dobeginj:=i;while(ord(s[j])<=ord('9')) and(ord(s[j])>=ord('0')) dobegina[k,1]:=a[k,1]*10+ord(s[j])-ord('0');...
道里区17686299008: 怎么计算时间复杂度(Pascal)?
以岚立将: 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道.但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了.并且一个算法花费的时间与算法中语句...
道里区17686299008: 如何计算Pascal 中时间复杂度 与 空间复杂度 - ?
以岚立将: 时间复杂度看循环的次数进行计算 比如你使用了两层for 循环 时间复杂度就是O(N^2),但这种估算是不准确的.有些算法的时间复杂度是固定的,比如迪杰斯特拉算法0(n^2) 弗洛伊德算法O(n^3) 空间复杂度现在联赛内存一般都是128MB 所以 限制不是很大 像一维数组开个几百万没问题
道里区17686299008: 在freepascal中一般时间复杂度为多少以下不会超时 - ?
以岚立将: 提问者根本不理解时间复杂度的概念,所以这个问题没人回答.说你不懂还不承认.一个算法的时间一般可以由 N:问题的规模 I:输入数据 A:算法本身 所决定,所以记算法的时间为这些参数的函数T=f(N,I,A) 如果让A隐含在复杂性函数的函数...
道里区17686299008: 程序空间复杂度/时间复杂度是怎么算的(最好说的是pascal) - ?
以岚立将: 空间复杂度主要是数据结构占的,拿数组来说,开1..n的数组,一般考试的内存限制可以开到n=10000000左右,就是10^7,时间复杂度根据程序的来算,拿循环来说,套用在一起的循环是相乘的 比如 for i:=1 to m do for j:=1 to n do begin …… ...
道里区17686299008: 时间复杂度和空间复杂度怎么计算 奢侈下 给个例子 - ?
以岚立将: 使用PASCAL语言讲解:a:=0; for i:=1 to 100 do a:=a+1;a初值为0,做100次累加,最后得结果a=100;加法是一种基本运算,所以这段程序的世间复杂度就是O(100).时间,空间复杂度都是O(N)来表示,N表示具体的数字.
道里区17686299008: floyed算法 pascal - ?
以岚立将: Floyd-Warshall 算法用来找出每对点之间的最短距离.它需要用邻接矩阵来储存边,这个算法通过考虑最佳子路径来得到最佳路径.注意单独一条边的路径也不一定是最佳路径.从任意一条单边路径开始.所有两点之间的距离是边的权,或者...
道里区17686299008: zoj 1074 Pascal解法?
以岚立将: 很高兴为你解答这道题,由于我接触pascal没多长时间,我事先写了c代码才把代码转为pascal的,所以请谅解现在才给你代码.我的运行结果是对的·你提交ac看看.我的思路就是动态规划.我一时也说不清楚·我也是看着代码然后自己带数...