链接:https://ac.nowcoder.com/acm/problem/21313
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
牛牛喜欢整数序列,他认为一个序列美丽的定义是
1:每个数都在0到40之间
2:每个数都小于等于之前的数的平均值
具体地说:for each i, 1 <= i < N, A[i] <= (A[0] + A[1] + ... + A[i-1]) / i.
3:没有三个连续的递减的数
现在给你一个序列,每个元素是-1到40,你可以将序列中的-1修改成任意的数,求你可以得到多少个美丽序列,答案对1e9+7取模
输入描述:
第一行输入一个整数n (1 ≤ n ≤ 40) 第二行输入n个整数
输出描述:
输出一个整数
示例1
输入
复制
2 3 -1
输出
复制
4
示例2
输入
复制
3 5 3 -1
输出
复制
2
示例3
输入
复制
3 -1 0 40
输出
复制
0
示例4
输入
复制
11 -1 40 -1 -1 -1 10 -1 -1 -1 21 -1
输出
复制
579347890
备注:
子任务1: n <= 10 子任务2: n <= 20 子任务3: 无限制
缺啥补啥
dp[i][j][flag][sum]处理完前i位,以j结尾,第flag个递减数,和为sum
暴力~~~
本地跑样例都有点慢,交上去竟然过了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll dp[45][45][3][1605];
int a[45];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
if(a[1]==-1){
for(int i=0;i<=40;i++) dp[1][i][1][i]=1;
}
else dp[1][a[1]][1][a[1]]=1;
for(int i=2;i<=n;i++){
if(a[i]==-1){
for(int j=0;j<=40;j++){
for(int k=0;k<=40;k++){
for(int sum=j*(i-1);sum<=1600-j;sum++){
if(j>=k){
dp[i][j][1][sum+j]+=dp[i-1][k][1][sum];
dp[i][j][1][sum+j]+=dp[i-1][k][2][sum];
dp[i][j][1][sum+j]%=mod;
}
else {
dp[i][j][2][sum+j]+=dp[i-1][k][1][sum];
dp[i][j][2][sum+j]%=mod;
}
}
}
}
}
else{
int j=a[i];
for(int k=0;k<=40;k++){
for(int sum=j*(i-1);sum<=1600-j;sum++){
if(j>=k){
dp[i][j][1][sum+j]+=dp[i-1][k][1][sum];
dp[i][j][1][sum+j]+=dp[i-1][k][2][sum];
dp[i][j][1][sum+j]%=mod;
}
else {
dp[i][j][2][sum+j]+=dp[i-1][k][1][sum];
dp[i][j][2][sum+j]%=mod;
}
}
}
}
}
ll ans=0;
for(int j=0;j<=40;j++){
for(int sum=j*n;sum<=1600;sum++){
ans+=dp[n][j][1][sum];
ans+=dp[n][j][2][sum];
ans%=mod;
}
}
printf("%lld\n",ans);
return 0;
}