hrbeu 1229 网络热身赛的一道DP Sum Of SubRectangular Parallelepiped(数字长方体)

好辛苦啊...热身赛的时候看错题目,没做出来..

今天实训逃回来,一个下午,WA了31次!。。。

 

#include <iostream> using namespace std; /* y=[x1x2x3..xn] 对于一维来说:y就是该列的值 对于二维来说:y是一个可变长度的向量 对于三维来说:y是一个长度可变数量可变的向量,形象的构成一个矩形 如果所有的情况都在一个数组里进行DP的话,那么本题需要开个5维数组... 5维的话是5次方,很明显是不可能的事情. 所以本体的策略是时间换空间. 由于数组不能开大,那么只能是每次计算一个矩形后,对使用的数组重新清零. 而一个矩形是3维的,所以开的数组数组只要3维就够了 */ #define MAX 315 #define big_one(x,y) (x > y ? x : y) //原数组 int mat3[MAX][MAX][MAX]; //降到二维的数组. int mat2[MAX][MAX]; //降到一维数组. int mat1[MAX]; //第一维,第二维,第三维 int L,M,N; int dp() { //返回c列序列的最大子序列和 int max1 = mat1[1]; int sum = mat1[1]; for (int c = 2;c <= N;c++) { //f[i] = f[i-1] > 0 ? f[i-1] : 0 + a[i] //从第二项开始 sum = big_one(sum,0) + mat1[c]; max1 = big_one(max1,sum); //cout<<"max :"<<max<<endl; } /* //f[i] = f[i]+a[i]>0?(f[i]+a[i]):0 //从第一项开始 int max1 = mat1[1]; int sum = 0; for (int c = 1;c <= N;c++) { sum += mat1[c]; max1 = big_one(max1,sum); if (sum < 0) { sum = 0; } } */ return max1; } int desc21() { //二维DP化成一维DP //用游标i,j来对x向量进行纵向移动,计算这一段的和,加到x向量中 //用max2来保存最大和 int max2 = 1<<32; for (int i = 1;i <= M;i++) { memset(mat1,0,sizeof(mat1)); for(int j = i;j <= M;j++) { for (int c = 1;c <= N;c++) { mat1[c] += mat2[j][c]; } max2 = big_one(dp(),max2); } } return max2; } int desc32() { //三维DP化成二维DP //用游标p,q来对二维数组进行移动,计算这一块的和到一个二维向量中 int max3 = 1<<32; for(int p = 1;p <= L;p++) { memset(mat2,0,sizeof(mat2)); for (int q = p;q <= L;q++) { for(int i = 1;i <= M;i++) for(int j = 1;j <= N;j++) { mat2[i][j] += mat3[q][i][j]; } max3 = big_one(desc21(),max3); } } return max3; } int main(char *argv[],int argc) { int t; cin>>t; while (t--) { cin>>L>>M>>N; for (int l = 1;l <= L;l++) { for (int m = 1;m <= M;m++) { for (int n = 1;n <= N;n++) { cin>>mat3[l][m][n]; } } } int ans = desc32(); cout<<(ans > 0 ? ans : 0)<<endl; } return 0; }

你可能感兴趣的:(c,网络)