列表

详情


DP8. 乘积为正数的最长连续子数组

描述

给定一个长度为 n 的整数数组,请你找出其中最长的乘积为正数的子数组长度。
子数组的定义是原数组中一定长度的连续数字组成的数组。

数据范围: , 数组中的元素满足

输入描述

第一行输入一个正整数 n ,表示数组长度。
第二行输入 n 个整数,表示数组中的元素。

输出描述

输出最长的乘积为正数的子数组长度

示例1

输入:

5
1 2 3 -5 1

输出:

3

示例2

输入:

5
1 2 3 0 5

输出:

3

原站题解

C++ 解法, 执行用时: 9ms, 内存消耗: 396KB, 提交时间: 2022-08-05

#include<cstdio>
#include<algorithm>

using namespace std;

template <typename T>
inline void read(T& f) {
	f = 0;
	T fu = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') {
			fu = -1;
		}
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		f = (f << 3) + (f << 1) + (c & 15);
		c = getchar();
	}
	f *= fu;
}
template <typename T>
inline void print(T x) {
	if (x < 0) putchar('-'), x = -x;
	if (x < 10) putchar(x + 48);
	else print(x / 10), putchar(x % 10 + 48);
}

int main(){
    int dpmaxn = 0, dpfmaxn = 0;        //以i结尾的正/负数和子数组最长长度
    int tmaxn, tfmaxn;
    int n, num, maxn = 0;
    
    read(n);
    while(n--){
        read(num);
        if(num > 0){
            tmaxn = dpmaxn + 1;
            tfmaxn = dpfmaxn == 0 ? 0 : dpfmaxn + 1;
        }
        else if(num < 0){
            tmaxn = dpfmaxn == 0 ? 0 : dpfmaxn + 1;
            tfmaxn = dpmaxn == 0 ? 1 : dpmaxn + 1;
        }
        else{
            tmaxn = tfmaxn = 0;
        }
        dpmaxn = tmaxn, dpfmaxn = tfmaxn;
        if(dpmaxn > maxn)maxn = dpmaxn;
    }
    print(maxn);
    
    return 0;
}

C++ 解法, 执行用时: 10ms, 内存消耗: 408KB, 提交时间: 2022-05-08

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int a[2][2];
inline int rd() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + ch - '0';
        ch = getchar();
    }
    return x * f;
}
int main() {
    int n;
    scanf("%d", &n);
    a[0][0] = -inf, a[0][1] = -inf;
    int MAX = 0;
    int x;
    for (int i = 1; i <= n; i++) {
        x = rd();
        int b = i % 2, t = (i - 1) % 2;
        if (x == 0)
            a[b][0] = -inf, a[b][1] = -inf;
        else if (x < 0) {
            a[b][0] = max(a[t][1] + 1, 1);
            if (a[t][0] == -inf) a[b][1] = -inf;
            else a[b][1] = a[t][0] + 1;
        } else {
            a[b][1] = max(a[t][1] + 1, 1);
            if (a[t][0] == -inf) a[b][0] = -inf;
            else a[b][0] = a[t][0] + 1;
        }
        MAX = max(MAX, a[b][1]);
    }
    printf("%d\n", MAX);
}

C++ 解法, 执行用时: 11ms, 内存消耗: 396KB, 提交时间: 2022-03-20

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int dp[2][2];
inline int rd() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }return x * f; }
int main() {
    int n;
    scanf("%d", &n);
    dp[0][0] = -inf, dp[0][1] = -inf;
    int maxx = 0;
    int x;
    for (int i = 1; i <= n; i++) {
        x=rd();
        int o = i % 2, t = (i - 1) % 2;
        if (x == 0) dp[o][0] = -inf, dp[o][1] = -inf;
        else if (x < 0) {
            dp[o][0] = max(dp[t][1] + 1, 1);
            if (dp[t][0] == -inf) dp[o][1] = -inf;
            else dp[o][1] = dp[t][0] + 1;
        } else {
            dp[o][1] = max(dp[t][1] + 1, 1);
            if (dp[t][0] == -inf) dp[o][0] = -inf;
            else dp[o][0] = dp[t][0] + 1;
        }
        maxx = max(maxx, dp[o][1]);
    }
    printf("%d\n", maxx);

}

C++ 解法, 执行用时: 13ms, 内存消耗: 2436KB, 提交时间: 2022-03-12

#include <bits/stdc++.h>

using namespace std;

int nums[100000+10];

int main() {
    int n = 0;
    scanf("%d", &n);
    vector<int> neg(n, 0), pos(n, 0);
    vector<int> dpMin(n, 0), dpMax(n, 0);
    for (int i = 0; i < n; i++) {
        scanf("%d", &nums[i]);
        if (nums[i] > 0) {
            pos[i] = 1;
        } else if (nums[i] == 0){
            neg[i] = 0;
            pos[i] = 0;
        } else {
            pos[i] = 0;
            neg[i] = 1;
        }
    }
    int imax = pos[0] != 0 ? pos[0] : 0;
    for (int i = 1; i < n; i++) {
        if (nums[i] == 0) {
            pos[i] = 0;
            neg[i] = 0;
        }
        // 前面是正序列 当前位置为正 正序列增长1
        if (pos[i-1] >= 1 && nums[i] > 0) {
            pos[i] = pos[i-1] + 1;
        }
        // 负序列增长正序列长度+1
        if (pos[i-1] >= 1 && nums[i] < 0) {
            neg[i] = pos[i-1] + 1;
        }
        if (neg[i-1] >= 1 && nums[i] > 0) {
            neg[i] = neg[i-1] + 1;
        }
        if (neg[i-1] >= 1 && nums[i] < 0) {
            pos[i] = neg[i-1] + 1;
        }
//         printf("%d ", pos[i]);
//         printf("%d\n", neg[i]);
        imax = max(imax, pos[i]);
    }
    printf("%d\n", imax);
    return 0;
}

C 解法, 执行用时: 16ms, 内存消耗: 688KB, 提交时间: 2022-03-30

#include <stdio.h>
#define max(x,y) (x)>(y)?(x):(y)
int main()
{
    int nums = 0;
    scanf("%d",&nums);
    int i = 0;
    int *aus = malloc(sizeof(int) * (nums + 1));
    int count = 0;
    int countbak = 0;
    int tmp = 1;
    int pos = 0;
    for(i = 0; i < nums; i ++)
    {
        scanf("%d",&aus[i]);
        if(aus[i] > 0)
        {
            count ++;
        }
        else if (aus[i] < 0)
        {
            tmp *= -1;
            if(tmp > 0)
            {
                pos ++;
                count += pos;
                pos = 0;
            }
            else
            {                
                pos += count;
                countbak = max(countbak,count);
                count = 0;
                pos ++;
            }                     
        }
        else
        {
            countbak = max(count, countbak);
            count = 0;
            pos = 0;
            tmp = 1;
        }
    }
    printf("%d", max(count, countbak));
    
}

上一题