AtCoder Regular Contest 122(补题)

A - Many Formulae

AtCoder Regular Contest 122(补题)
AtCoder Regular Contest 122(补题)AtCoder Regular Contest 122(补题)
题意: 给定一个长度为n的数组,在两个数之间加‘+’或‘-’,但是不能连续加两个‘-’号,在上述规则下,求出n个数在所有‘+’‘-’号组合的和,并取余109+7
思路: 建立两个二维数组 d p [ N ] [ 2 ] dp[N][2] dp[N][2],用 d p [ i ] [ + ] 和 d p [ i ] [ − ] dp[i][+]和dp[i][-] dp[i][+]和dp[i][−]分别表示当前这个数的符号为‘+’和‘-’的答案
w a y [ i ] [ + ] 和 w a y [ i ] [ − ] way[i][+]和way[i][-] way[i][+]和way[i][−]分别表示当前这个数的符号为 ‘ + ’ 和 ‘ − ’ ‘+’和‘-’ ‘+’和‘−’的方案数。
当前符号为’+'时,上一个符号可为’+‘可为’-’,所以 w a y [ i ] [ + ] = w a y [ i − 1 ] [ − ] + w a y [ i − 1 ] [ + ] way[i][+]=way[i-1][-]+way[i-1][+] way[i][+]=way[i−1][−]+way[i−1][+]

d p [ i ] [ + ] = d p [ i − 1 ] [ + ] + w a y [ i − 1 ] [ 1 ] ∗ a [ i ] + d p [ i − 1 ] [ − ] + w a y [ i − 1 ] [ 0 ] ∗ a [ i ] dp[i][+]=dp[i-1][+]+way[i-1][1]*a[i]+dp[i-1][-]+way[i-1][0]*a[i] dp[i][+]=dp[i−1][+]+way[i−1][1]∗a[i]+dp[i−1][−]+way[i−1][0]∗a[i]
因为当前第 i i i号数字位置符号为‘+’,那现在的得数,就是前面 i − 1 i-1 i−1个数各种组合所得数,加上当前这个值,因为是在不同的合法组合中加上的 a [ i ] a[i] a[i],所以加上的是不同的方案数 ∗ a [ i ] *a[i] ∗a[i]

当前符号位’-'时,上一个符号只能为’+’,所以
w a y [ i ] [ − ] = w a y [ i − 1 ] [ + ] way[i][-]=way[i-1][+] way[i][−]=way[i−1][+]

d p [ i ] [ − ] = d p [ i − 1 ] [ + ] − w a y [ i − 1 ] [ + ] ∗ a [ i ] dp[i][-]=dp[i-1][+]-way[i-1][+]*a[i] dp[i][−]=dp[i−1][+]−way[i−1][+]∗a[i]
因为当前第 i i i号数字位置符号为‘-’,那现在的得数,就是前面 i − 1 i-1 i−1个数各种组合所得数,减去当前这个值,因为是在不同的合法组合中减去的 a [ i ] a[i] a[i],所以减去的是不同的方案数 ∗ a [ i ] *a[i] ∗a[i]

对于取模,为了防止出错,我基本在每一步运算中都取模了,并把数组考了long long

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int n;
ll dp[N][2], w[N][2];
ll a[N];

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%lld", &a[i]);
    }
    dp[1][0] = a[0];
    w[1][0] = 1;
    for (int i = 1; i < n; i++) {
        dp[i + 1][0] = (dp[i][0] + dp[i][1]) % mod + (a[i] * w[i][0]) % mod +(a[i] * w[i][1]) % mod;
        dp[i + 1][1] = (dp[i][0] - a[i] * w[i][0] + mod) % mod;
        w[i + 1][0] = (w[i][0] + w[i][1]) % mod;
        w[i + 1][1] = w[i][0];
    }
    printf("%lld\n", (dp[n][0] + dp[n][1]) % mod);
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

上一篇:【反转(开关问题)】Face The Right Way


下一篇:将没有目标的图片抽出数据集文件夹