"Algorithm Contest·Quick 300 Questions" one question per day: "product"

" Algorithm Competition: 300 Quick Questions " will be published in 2024, and it is an auxiliary workbook for "Algorithm Competition" .
All questions are placed in the self-built OJ New Online Judge .
The codes are provided in C/C++, Java, and Python. The topics are mainly low-to-medium level, suitable for beginners and advanced.


" Product ", link: http://oj.ecustacm.cn/problem.php?id=1781

topic description

[Title description] You are given a sequence of length n, and the elements in the sequence only include 1 and -1.
How many consecutive subsequences have a positive product.
【Input format】 Enter the first row as a positive integer n. (n does not exceed 10^6)
The second line contains n integers.
[Output Format] Output an integer to represent the answer.
【Input sample】

4
1 1 -1 -1

【Example of output】

6

answer

  This is a classic question. The multiplication of an even number of -1s is a positive number, and the multiplication of an odd number of -1s is a negative number. This question can obviously be done with DP, and the DP state and transition equations are designed below.
  Let the input sequence be a[1]~a[n], define the DP state as:
    dp[i][0]: the number of products ending with a[i] is 1 dp[i][1]: the number of products ending with a[i] being -1 For
    example, {1
  , 1, -1, -1} of the sample, there are: dp[1][0]=1, dp[2][0]=2, dp[3][0]=0, dp[4 ][0]=3.   The total computational complexity of DP is O(n).   There are other solutions to this question, please think for yourself. 【Key Point】 Linear DP.









C++ code

#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
int a[N];
long long dp[N][2];  //dp[i][0]:以a[i]结尾的积为1的个数;dp[i][1]:以a[i]结尾的积为-1的个数
long long ans;
int main(){
    
    
    int n; cin >> n;
    for(int i = 1;i <= n;i ++) cin >> a[i];
    for(int i = 1;i <= n;i ++){
    
    
        if(a[i] == 1){
    
    
            dp[i][0] = dp[i-1][0] + 1;  //积为1的个数再加1(就是加自己)
            dp[i][1] = dp[i-1][1];      //积继续为-1,只能1乘以积为-1的dp
        }
        else if(a[i] == -1){
    
    
            dp[i][0] = dp[i-1][1];      // -1乘以积为-1的dp ,积才为1
            dp[i][1] = dp[i-1][0] + 1;  // -1 乘以积为1的dp,积才为-1, 再加上1(自己)
        }
    }
    for(int i=1;i<=n;i++)  ans = ans + dp[i][0];   //将所有积为1的dp求和,即为总个数
    cout << ans << endl;
    return 0;
}

java code

import java.util.Scanner;
public class Main {
    
    
    static final int N = 1000010;
    static int[] a = new int[N];
static long[][] dp = new long[N][2]; 
//dp[i][0]:以a[i]结尾的积为1的个数;dp[i][1]:以a[i]结尾的积为-1的个数
    static long ans;
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 1; i <= n; i++)  a[i] = sc.nextInt();        
        for (int i = 1; i <= n; i++) {
    
    
            if (a[i] == 1) {
    
    
                dp[i][0] = dp[i - 1][0] + 1;  //积为1的个数再加1(就是加自己)
                dp[i][1] = dp[i - 1][1];      //积继续为-1,只能1乘以积为-1的dp
            } else if (a[i] == -1) {
    
    
                dp[i][0] = dp[i - 1][1];      // -1乘以积为-1的dp ,积才为1
                dp[i][1] = dp[i - 1][0] + 1;  // -1 乘以积为1的dp,积才为-1, 再加上1(自己)
            }
        }
        for (int i=1; i<=n; i++)   ans += dp[i][0]; //将所有积为1的dp求和,即为总个数
        System.out.println(ans);
    }
}

Python code

N = 1000010
a = [0] * N
dp = [[0] * 2 for _ in range(N)]  
# dp[i][0]:以a[i]结尾的积为1的个数;dp[i][1]:以a[i]结尾的积为-1的个数
ans = 0
n = int(input())
a[1:n + 1] = list(map(int, input().split()))
for i in range(1, n + 1):
    if a[i] == 1:
        dp[i][0] = dp[i - 1][0] + 1        # 积为1的个数再加1(就是加自己)
        dp[i][1] = dp[i - 1][1]            # 积继续为-1,只能1乘以积为-1的dp
    elif a[i] == -1:
        dp[i][0] = dp[i - 1][1]            # -1乘以积为-1的dp ,积才为1
        dp[i][1] = dp[i - 1][0] + 1        # -1 乘以积为1的dp,积才为-1, 再加上1(自己)

for i in range(1, n+1): ans += dp[i][0]    # 将所有积为1的dp求和,即为总个数
print(ans)

Guess you like

Origin blog.csdn.net/weixin_43914593/article/details/131810636