区间dp
1 //hdu 1087 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <vector> 9 #include <cmath> 10 using namespace std; 11 #define max(a,b) a>b?a:b 12 typedef long long ll; 13 const int inf=0x3f3f3f3f; 14 int n; 15 const int N =1200; 16 ll a[N]; 17 ll dp[N]; 18 int main(){ 19 while(~scanf("%d",&n)&&n){ 20 for(int i=1;i<=n;i++) 21 { 22 scanf("%lld",&a[i]); 23 } 24 memset(dp,0,sizeof(dp)); 25 dp[1]=a[1]; 26 for(int i=2;i<=n;i++) 27 { 28 for(int j=1;j<i;j++) 29 { 30 if(a[i]>a[j]) 31 { 32 dp[i]=max(dp[i],dp[j]+a[i]); 33 } 34 } 35 dp[i]=max(dp[i],a[i]);//仅有自己 36 } 37 ll maxx=0; 38 for(int i=1;i<=n;i++) 39 { 40 maxx=max(dp[i],maxx); 41 } 42 printf("%lld\n",maxx); 43 } 44 return 0; 45 }
1 // hdu1024(动态规划+滚动数组优化) 2 //http://blog.csdn.net/pmt123456/article/details/52695470 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <utility> 9 #include <vector> 10 #include <map> 11 #include <queue> 12 #include <stack> 13 #include <cstdlib> 14 typedef long long ll; 15 #define lowbit(x) (x&(-x)) 16 #define ls l,m,rt<<1 17 #define rs m+1,r,rt<<1|1 18 using namespace std; 19 //const int N=1e6+9; 20 #define N 1000000+9 21 //const int inf=0x3f3f3f3f; 22 #define inf 0x3f3f3f3f 23 int n,m,a[N],dp[N],pre[N]; 24 int main() 25 { 26 while(~scanf("%d%d",&m,&n)) 27 { 28 for (int i=1;i<=n;i++) 29 { 30 scanf("%d",&a[i]); 31 } 32 memset(dp,0,sizeof(dp)); 33 memset(pre,0,sizeof(pre)); 34 //dp,pre都要先初始化为0 35 int tmp; 36 for (int i=1;i<=m;i++) 37 { 38 tmp=-inf;//最后i==m时tmp再次从-inf开始 39 for (int j=i;j<=n;j++) 40 { 41 dp[j]=max(dp[j-1],pre[j-1])+a[j];//此时的pre[j-1]是i-1时得到的 42 pre[j-1]=tmp;//此时的pre[j-1]为i+1做准备 43 tmp=max(tmp,dp[j]);//分成m组,但是最后一个元素的下标不一定 44 //printf("%d\n",tmp); 45 } 46 } 47 printf("%d\n",tmp);//最终求出的tmp一定是分成m个区间的最大值 48 } 49 return 0; 50 }
1 /* 2 蓝桥杯 历届试题 最大子阵 3 问题描述 4 给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。 5 其中,A的子矩阵指在A中行和列均连续的一块。 6 输入格式 7 输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。 8 接下来n行,每行m个整数,表示矩阵A。 9 输出格式 10 输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。 11 样例输入 12 3 3 13 -1 -4 3 14 3 4 -1 15 -5 -2 8 16 样例输出 17 10 18 样例说明 19 取最后一列,和为10。 20 数据规模和约定 21 对于50%的数据,1<=n, m<=50; 22 对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。 23 24 */ 25 //非空子阵 26 #include <iostream> 27 #include <cstdio> 28 #include <cstring> 29 #include <string> 30 #include <algorithm> 31 #include <utility> 32 #include <vector> 33 #include <map> 34 #include <queue> 35 #include <stack> 36 #include <cstdlib> 37 typedef long long ll; 38 #define lowbit(x) (x&(-x)) 39 #define ls l,m,rt<<1 40 #define rs m+1,r,rt<<1|1 41 using namespace std; 42 const int N=550; 43 int a[N][N],dp[N]; 44 int n,m; 45 int maxx=-5500; 46 int tmp; 47 int solve(int n,int m) 48 { 49 //枚举起始行和终点行 50 for(int i=0;i<n;i++) 51 { 52 memset(dp,0,m*sizeof(int)); 53 //每次换起始行dp要初始化为0 54 for(int j=i;j<n;j++) 55 { tmp=-5500;//只要起始行和终点行确定了,tmp就要从最小值开始 56 for(int k=0;k<m;k++) 57 { 58 dp[k]+=a[j][k]; 59 tmp+=dp[k]; 60 if(tmp<dp[k]) tmp=dp[k];//从k开始会更大 61 if(maxx<tmp) maxx=tmp; 62 } 63 } 64 } 65 return maxx; 66 } 67 int main() 68 { 69 scanf("%d%d",&n,&m); 70 for(int i=0;i<n;i++) 71 { 72 for(int j=0;j<m;j++) 73 { 74 scanf("%d",&a[i][j]); 75 } 76 } 77 printf("%d\n",solve(n,m)); 78 return 0; 79 }