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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮