链接: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操作,挺不错的一道题
来自:https://www.cnblogs.com/BlogOfchc1234567890/p/9862075.html
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define in(x) scanf("%d",&x)
#define ind(x) scanf("%lld",&x)
#define out(x) printf("%d ",x);
#define outln(x) printf("%lld\n",x);
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
#define PE(x,y) x=((x)+(y))%mod
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll powmod(ll a,ll b) {ll res=1;a%=mod;
for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=44;
int dp[N][N][5][1700];
int a[N],t,n;
int main()
{
in(n);
rep(i,1,n) in(a[i]);
if(a[1]!=-1) dp[1][a[1]][1][a[1]]=1;
else rep(i,0,40) dp[1][i][1][i]=1;
rep(i,2,n){
if(a[i]!=-1){
rep(sum,(i-1)*a[i],1600-a[i]){
int newsum=sum+a[i];
rep(last,0,40){
if(a[i]<last) PE(dp[i][a[i]][2][newsum],dp[i-1][last][1][sum]);
else{
PE(dp[i][a[i]][1][newsum],dp[i-1][last][2][sum]);
PE(dp[i][a[i]][1][newsum],dp[i-1][last][1][sum]);
}
}
}
}
else{
rep(newlast,0,40){
rep(sum,(i-1)*newlast,1600-newlast){
int newsum=sum+newlast;
rep(last,0,40){
if(newlast<last){
PE(dp[i][newlast][2][newsum],dp[i-1][last][1][sum]);
}
else{
PE(dp[i][newlast][1][newsum],dp[i-1][last][2][sum]);
PE(dp[i][newlast][1][newsum],dp[i-1][last][1][sum]);
}
}
}
}
}
}
ll ans=0;
rep(last,0,40)
rep(len,1,2)
rep(sum,0,1600)
PE(ans,dp[n][last][len][sum]);
outln(ans);
}