【517Coding】可爱序列
可爱序列
描述
计算鸭喜欢序列,他认为如下的序列是可爱的
1:序列中的元素大于等于 \(0\) 小于等于 \(40\)
2:序列中每个元素都不大于之前的数的平均值
3:没有三个连续的递减的数
有一个序列 \(a (−1≤a_i≤40-1)\)
你可以将 \(-1\) 变成任意整数,求 \(a\) 序列可以变成多少不同的可爱序列,答案对 \(10^9+7\) 取模
输入
第一行输入一个整数 \(n\)
第二行输入 \(n\) 个整数
输出
输出一个整数
数据范围
100%的数据: \(n ≤ 40\)
题解
可爱你马。
设 \(dp[i][j][0/1][k]\) ,为选择到第 \(i\) 位,第 \(i\) 位选 \(j\) ,这一位是否小于上一位 ,已经选择的数的总和
转移方程很显然。
#include<bits/stdc++.h>
using namespace std;
#define long long int
const int mod=1e9+7;
int n;
int a[50];
int dp[50][50][2][1610];
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
}
if(a[1]!=-1){
dp[1][a[1]][0][a[1]]=1;
}
else {
for(int i=0;i<=40;++i){
dp[1][i][0][i]=1;
}
}
for(int i=2;i<=n;++i){
if(a[i]!=-1){
for(int j=a[i]*(i-1);j<=1600-a[i];++j){
for(int k=0;k<=a[i];++k){
dp[i][a[i]][0][j+a[i]]+=dp[i-1][k][0][j];
dp[i][a[i]][0][j+a[i]]%=mod;
dp[i][a[i]][0][j+a[i]]+=dp[i-1][k][1][j];
dp[i][a[i]][0][j+a[i]]%=mod;
}
for(int k=a[i]+1;k<=40;++k){
dp[i][a[i]][1][j+a[i]]+=dp[i-1][k][0][j];
dp[i][a[i]][1][j+a[i]]%=mod;
}
}
}
else {
for(a[i]=0;a[i]<=40;++a[i]){
for(int j=a[i]*(i-1);j<=1600-a[i];++j){
for(int k=0;k<=a[i];++k){
dp[i][a[i]][0][j+a[i]]+=dp[i-1][k][0][j];
dp[i][a[i]][0][j+a[i]]%=mod;
dp[i][a[i]][0][j+a[i]]+=dp[i-1][k][1][j];
dp[i][a[i]][0][j+a[i]]%=mod;
}
for(int k=a[i]+1;k<=40;++k){
dp[i][a[i]][1][j+a[i]]+=dp[i-1][k][0][j];
dp[i][a[i]][1][j+a[i]]%=mod;
}
}
}
}
}
int ans=0;
for(int i=0;i<=40;++i){
for(int j=0;j<=40*n;++j){
ans+=dp[n][i][0][j];
ans%=mod;
ans+=dp[n][i][1][j];
ans%=mod;
}
}
printf("%lld\n",ans);
}