NYOJ104——动态规划的运用
2012-11-09 18:14
211 查看
每一道题目,只要你愿意耐心的去发现它的思路,你会发现其中其乐无穷。
题目非常简单,就是求一个子矩阵使得其各项的和最大。
在这里我们先回想一下求一个数组的最大连续字串和,假定一整形数列{a1,a2,a3,...,an},找出连续的非空子串{ax,ax+1,ax+2,...,ax+y},使得该子序列的的和最大。思路:假设F[m]表示以第m个数结尾的最大连续字串和,则F[m]=max{F[m-1],0}+a[m],然后再求出F[m]数组中的最大值即可,代码为:
联系本题,即将二维转化为一维,分析如下:
假设最大子矩阵的结果为从第r行到k行、从第i列到j列的子矩阵,如下所示(ari表示a[r][i],假设数组下标从1开始):
| a11 …… a1i ……a1j ……a1n |
| a21 …… a2i ……a2j ……a2n |
| . . . . . . . |
| . . . . . . . |
| ar1 …… ari ……arj ……arn |
| . . . . . . . |
| . . . . . . . |
| ak1 …… aki ……akj ……akn |
| . . . . . . . |
| an1 …… ani ……anj ……ann |
那么我们将从第r行到第k行的每一行中相同列的加起来,可以得到一个一维数组如下:
(ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
由此我们可以看出最后所求的就是此一维数组的最大子断和问题,到此我们已经将问题转化为上面的已经解决了的问题了。
题目非常简单,就是求一个子矩阵使得其各项的和最大。
在这里我们先回想一下求一个数组的最大连续字串和,假定一整形数列{a1,a2,a3,...,an},找出连续的非空子串{ax,ax+1,ax+2,...,ax+y},使得该子序列的的和最大。思路:假设F[m]表示以第m个数结尾的最大连续字串和,则F[m]=max{F[m-1],0}+a[m],然后再求出F[m]数组中的最大值即可,代码为:
maxsum=-INT_MAX; scanf("%d",&m); for(int i=1;i<=m;++i) { scanf("%d",&a[i]); if(a[i-1]>0) a[i]+=a[i-1]; if(a[i]>maxsum) maxsum=a[i]; } printf("%d\n",maxsum);
联系本题,即将二维转化为一维,分析如下:
假设最大子矩阵的结果为从第r行到k行、从第i列到j列的子矩阵,如下所示(ari表示a[r][i],假设数组下标从1开始):
| a11 …… a1i ……a1j ……a1n |
| a21 …… a2i ……a2j ……a2n |
| . . . . . . . |
| . . . . . . . |
| ar1 …… ari ……arj ……arn |
| . . . . . . . |
| . . . . . . . |
| ak1 …… aki ……akj ……akn |
| . . . . . . . |
| an1 …… ani ……anj ……ann |
那么我们将从第r行到第k行的每一行中相同列的加起来,可以得到一个一维数组如下:
(ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
由此我们可以看出最后所求的就是此一维数组的最大子断和问题,到此我们已经将问题转化为上面的已经解决了的问题了。
在此插入代码,仔细分析一下三个for循环,便可发现这道题也是挺easy的
#include<stdio.h> #include<string.h> const int MAX=102; int arr[MAX][MAX]; //定义参数max接收最大值 int max; int row,col; //得到每一行连续的最大值 void getMax(int a); int main() { //freopen("in.txt","r",stdin); int n; scanf("%d",&n); while(n--) { memset(arr,0,sizeof(arr)); scanf("%d%d",&row,&col); for(int i=1;i<=row;++i) { for(int j=1;j<=col;++j) { scanf("%d",&arr[i][j]); } } max=arr[1][1]; for(int i=1;i<=row;++i) { getMax(i);//获得第i行的最大连续子串和 for(int j=i+1;j<=row;++j) { for(int k=1;k<=col;++k) arr[i][k]+=arr[j][k]; getMax(i);//获得第i行至第j行的最大连续子串和 } } printf("%d\n",max); } } void getMax(int a) { int temp=0; for(int i=1;i<=col;++i) { if(temp>0) temp+=arr[a][i]; else temp=arr[a][i]; if(temp>max) max=temp; } }
相关文章推荐
- NYOJ 104 矩阵最大和 - 简单动态规划
- NYOJ 104 最大和 和POJ 1050 To the Max【动态规划】
- nyoj104最大和--中等难度--动态规划
- 【POJ1050】To the Max (动态规划、最大字串和、最大子矩阵和)||NYOJ44 ||NYOJ104
- (NYoj 104)最大和 --二维最大连续子串和转化为一维,动态规划
- NYOJ 题目104最大和(动态规划)
- NYOJ-16-矩形嵌套(动态规划)
- nyoj 104——最大和——————【子矩阵最大和】
- nyoj-36 最长公共子序列(动态规划 或 递归)
- (NYoj 61) 传纸条(1) 动态规划,双向dp
- NYOJ 104 最大和
- nyoj 开心的小明 动态规划 01背包
- nyoj 104 最大和
- NYOJ-104最大和(动归题)及连续最大和核心
- NYOJ 79.拦截导弹(动态规划)
- nyoj 79 拦截导弹 连续递减最长子序列(动态规划)
- nyoj 104 最大和 【dp】
- NYOJ 16 矩形嵌套(动态规划)
- NYOJ-104最大和
- 最大和 NYOJ——104