《蓝桥杯算法》最长子序列和最大矩阵的和
文章目录
一、最长子序列
1.暴力算法(时间复杂度(O(n^2))
源代码:
#include <iostream>
using namespace std;
int main()
{
int a[7] = {3, -2, -4, 5, -2, 6, -3};
int max = -10;
for(int i = 0; i < 7; i++){
int sum = a[i];
for(int j = i+1; j < 7; j++){
sum += a[j];
if(max < sum){
max = sum;
}
}
}
cout<<max;
return 0;
}
2.动态规划(时间复杂度(O(n))
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[200005];
int dp[200005];
int main()
{
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%d",&a[i]);
}
dp[0] = a[0];
int ma = a[0];
for(int i = 1; i < n; i++){
dp[i] = max(dp[i-1] + a[i] , a[i]);
if( ma < dp[i]){
ma = dp[i];
}
}
printf("%d\n", ma);
return 0;
}
二、最大子矩阵
1.暴力算法(时间复杂度(O(n^6))
#include <iostream>
using namespace std;
int a[100][100];
int main()
{
int n , m;
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
}
}
int ans = 1 << 31;
for(int i = 1; i <= n; i++){ //卡住上下边界
for(int j = 1; j<= m; j++){
for(int k = i; k <=n ; k++){ //卡住左右边界
for(int l = j; l <= m; l++){
int sum = 0;
for(int p = i; p <= k; p++){ //两个指针在里面扫描
for(int q = j; q <= l; q++){
sum += a[p][q];
}
}
ans = max(ans , sum);
}
}
}
}
printf("%d\n",ans);
return 0;
}
2.略微优化(时间复杂度(O(n^4))
#include <iostream>
#include <algorithm>
using namespace std;
int a[55][55];
int pre[55][55];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
for(int j = 1; j <=m; j++){
scanf("%d",&a[i][j]);
pre[i][j] = pre[i-1][j] + pre[i][j-1] - pre[i-1][j-1] + a[i][j];
}
}
int sum = a[1][1];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
for(int k = i; k <= n; k++){
for(int l = j; l <= m; l++){
sum = max(sum , pre[k][l] - pre[i -1][l] - pre[k][j-1] + pre[i-1][j-1]);
}
}
}
}
printf("%d\n",sum);
return 0;
}
3.动态规划(时间复杂度(O(n^3))
#include <iostream>
#include <algorithm>
using namespace std;
int a[55][55];
int pre[55][55];
int dp[55];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
pre[i][j] = pre[i-1][j] + a[i][j];
}
}
int sum = 1 << 31;
for(int i = 1; i <= n; i++){
for(int j = i; j<=n; j++){
dp[1] = pre[j][1] - pre[i-1][1];
for(int k = 2; k <= m; k++){
int tem = pre[j][k] - pre[i-1][k];
dp[k] = max( dp[k-1] + tem,dp[k]);
sum = max(sum , dp[k]);
}
}
}
printf("%d\n",sum);
return 0;
}