题目:https://vjudge.z180.cn/contest/418424#problem/I
题意:给你三个条件,问能凑出多少个序列满足这些条件
思路:
判断不符合的条件就不说了,
如果它符合,则序列数为零的时候,答案是1,
从前往后跑,如果这一个比前一个大,说明,刚加入的这个数要么比前面所有数大,那么会更新h数组,要么比前面的最小值小,也会更新h数组;当这个数和前一个是相等的时候,说明,刚加入的这个值并没有改变最大值和最小值,所以它一定是最大值和最小值之间的某个数,并且这个数未加入到序列中,即每次hi - h(i - 1)的个数-1,比如说1 ~ 3,1和3不能用了,我们只能用2,则cnt = (3 - 1) - 1;
具体看代码:
#include <bits/stdc++.h>
#define x first
#define y second
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const ll llINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const double DINF = 1e20;
const double eps = 1e-15;
const double PI = acos(-1.0);
const int mod = 1e9 + 7;
const int N = 1e5 + 50;
int h[N];
int main()
{
int T; scanf("%d", &T);
while (T--) {
int n; scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
bool flag = true;
if (h[1] != 0) flag = false;
if (h[n] != n - 1) flag = false;
for (int i = 2; i <= n; i++) {
if (h[i] < h[i - 1]) flag = false;
}
if (!flag) puts("0");
else {
ll res = 1; // 不凑的时候(没有字符的时候)
int cnt = 0;
for (int i = 2; i <= n; i++) {
if (h[i] > h[i - 1]) {
res = (res * 2) % mod;
cnt += h[i] - h[i - 1] - 1;
} else {
res = (res * cnt) % mod;
cnt--;
}
}
printf("%lld\n", res);
}
}
return 0;
}