NYOJ 104(最大和)
这是一道动态规划题目,利用一维数列的最大子段和求多维的最大子段和。
下列代码中的 psub()子函数就是求一维数列的动态规划。
我们依次吧几行数据加到一行上相当于选中了好几行,然后再判断取几列能使其最大。
自己的代码:
View Code
1 #include<stdio.h> 2 3 int map[101][101]; 4 int sum; 5 int r,c; 6 7 void psub(int i) 8 { 9 int j,t=0; 10 for(j=0;j!=c;++j) 11 { 12 if(t>0)t+=map[i][j]; 13 else t=map[i][j]; 14 if(t>sum)sum=t; 15 } 16 } 17 18 void slove() 19 { 20 int i,j,k; 21 for(i=0;i!=r;++i) 22 { 23 psub(i); 24 for(j=i+1;j!=r;++j) 25 { 26 for(k=0;k!=c;++k) 27 map[i][k]+=map[j][k]; 28 psub(i); 29 } 30 } 31 } 32 33 int main() 34 { 35 int n,i,j; 36 scanf("%d",&n); 37 while(n--) 38 { 39 scanf("%d%d",&r,&c); 40 for(i=0;i!=r;++i) 41 for(j=0;j!=c;++j) 42 scanf("%d",&map[i][j]); 43 sum=map[0][0]; 44 slove(); 45 printf("%d\n",sum); 46 } 47 //scanf("%d",&n); 48 return 0; 49 }
借鉴的代码(简洁):
#include<stdio.h> int a[101][101]; int b[101]; int main() { int r,c,i,j,k,t,sum; scanf("%d",&t); while(t--) { scanf("%d%d",&r,&c); for(i=1;i<=r;++i) for(j=1;j<=c;++j) { scanf("%d",&a[i][j]); a[i][j]+=a[i-1][j]; } sum=a[1][1]; for(i=0;i<=r-1;++i) for(j=i+1;j<=r;++j) { for(k=0;k<=c;++k) b[k]=0; for(k=1;k<=c;++k) { if(b[k-1]>0)b[k]=b[k-1]+a[j][k]-a[i][k]; else b[k]=a[j][k]-a[i][k]; if(b[k]>sum)sum=b[k]; } } printf("%d\n",sum); } return 0; }