SDUT 2022 Summer Individual Contest - 10 (补题)
题目链接:
Many Formulae - AtCoder arc122
题意:
不能存在两个及两个以上的减号,所有满足条件的式子之和。
分析:
对于一个位置选+与选-的问题首先想到dp
设置dp数组dp[i][0]表示最后一个符号是+的答案值
设置dp数组dp[i][1]表示最后一个符号是-的答案值
那么答案则是(dp[n][0]+dp[n][1])%mod
还需要设置一个cnt数组表示以+或-结尾的总选择数
因为不能同时出现两个-
所以cnt[i][1]=cnt[i-1][0];(最后一个符号是-则倒数第二个符号必须是+)
cnt[i][0]=(cnt[i-1][0]+cnt[i-1][1])%mod;
根据上述的状态转移方程即可
#include <bits/stdc++.h> #define endl '\n' #define x first #define y second #define int long long #define PI acos(-1) #define SugarT ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; const int N=1e5+10; const int M=510; const int INF=0x3f3f3f3f; const int mod=1e9+7; const double eps = 1e-6; int n; int q[N]; int dp[N][2]; int cnt[N][2]; void solve() { cin >> n; for(int i=1;i<=n;i++)cin >> q[i]; dp[1][0]=q[1]; cnt[1][0]=1; for(int i=2;i<=n;i++){ cnt[i][0]=(cnt[i-1][0]+cnt[i-1][1])%mod; cnt[i][1]=cnt[i-1][0]; dp[i][0]=(dp[i-1][0]+dp[i-1][1]+cnt[i][0]*q[i]%mod)%mod; dp[i][1]=(dp[i-1][0]-cnt[i-1][0]*q[i]%mod+mod)%mod; } cout << (dp[n][0]+dp[n][1])%mod << endl; } signed main() { SugarT int T=1; //cin >> T; while(T--) solve(); return 0; }