返回顶部

Tokio Marine & Nichido Fire Insurance Programming Contest 2021(AtCoder Regular Contest 122) A - Many Formulae (dp)

  • 题意:有\(n\)个序列,每两个数之间可以放\(+\)\(-\),但是不能存在两个及以上的\(-\),写出全部不同的多项式,求这些多项式的和。

  • 题解:设\(dp[i][0/1]\)表示前\(i\)个数并且当前符号为\(+\)\(-\)的情况,先不考虑\(+/-\)\(i\)个数的情况,那么很明显\(dp[i][0]=dp[i-1][0]+dp[i-1][1]\)\(dp[i][1]=dp[i-1][0]\),现在考虑\(+/-\)\(i\)个数的情况,也就是说当前\(+、/-\)的时候 前面有多少种方案数,记\(f[i][0/1]\)表示第\(i\)个位置放\(+/-\)的方案数,递推一下发现转移方程:\(f[i][0]=f[i-1][0]+f[i-1][1]\),\(f[i][1]=f[i-1][0]\),那么最后的\(dp\)转移方程为:\(dp[i][0]=dp[i-1][0]+dp[i-1][1]+f[i][0]*a[i]\),\(dp[i][1]=dp[i-1][0]-f[i][1]*a[i]\).

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int n;
    int a[N];
    ll f[N][2];
    ll dp[N][2];  //0:+ 1:-
    
    int main() {
        scanf("%d",&n);
        f[1][0]=1;
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
        }
        for(int i=2;i<=n;++i){
            f[i][0]=(f[i-1][0]+f[i-1][1])%mod;
            f[i][1]=f[i-1][0];
        }
        dp[1][0]=a[1];
        for(int i=2;i<=n;++i){
            dp[i][0]=(dp[i-1][0]+dp[i-1][1]+f[i][0]*a[i]%mod)%mod;
            dp[i][1]=(dp[i-1][0]-f[i][1]*a[i]%mod+mod)%mod;
        }
        printf("%lld",(dp[n][0]+dp[n][1])%mod);
        return 0;
    }
    
    
posted @ 2021-09-18 13:45  Rayotaku  阅读(61)  评论(0编辑  收藏  举报