I - Interesting Permutation 纯思维

题目: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;
}

猜你喜欢

转载自blog.csdn.net/YingShen_xyz/article/details/115554692