2019牛客暑期多校训练营(第九场) F Birthday Reminders(dp)

链接:https://ac.nowcoder.com/acm/contest/889/F
来源:牛客网
 

题目描述

Today is Tomori's birthday! Usually, people get many birthday wishes on social media, but Tomori has decided to hide her birthday on social media, and thus does not expect many (if any) wishes from her friends. 

Tomori has N friends. Some of the friends actually remembered her birthday! For each friend $i$, he or she will remember Tomori's birthday at time ti and give her a birthday wish at that instant (or not remember her birthday at all if ti=−1t_i = -1ti​=−1).

Some of Tomori's friends are very considerate however, and decides to remind others about her birthday. Friend i will remind friend pi about Tomori's birthday after he or she has wished her. Formally, if Friend i gave Tomori a birthday wish at time t, then he or she will remind friend pi to give Tomori a birthday wish at time t+1 (and friend pi will give her a birthday wish at time t+1 and remind friend ppip_{p_{i}}ppi​​ at time t+2 and so on, assuming that they have not already gave her a birthday wish). The sequence pi forms a permutation, i.e. each friend will be reminded by exactly one friend. Note that pi=ip_i = ipi​=i is possible, which means that the friend will not remind anyone about Tomori's birthday after sending their wish.

The day is over and at the end of the day, Tomori receives the wish from Friend i at time bib_ibi​ (if bi=−1b_i = -1bi​=−1, it means that friend i never wished her for her birthday). Note that bib_ibi​ might not be equal to tit_iti​ as he or she might be reminded by another friend at an earlier time. 

Tomori receives the wishes, but she actually can't distinguish between her friends, so she only knows the number of wishes she received at each particular time. Now, she wonders, over all possible permutations {pi}\{p_i\}{pi​}, how many possible different days she could have experienced. Two permutations p, q correspond to different days if at some point of time, the number of friends who wished Tomori was different.

输入描述:

The first line of input contains a single integer N (1 <= N <= 100).

The next line of input contains N space-separated integers, the i-th of which denotes ti (ti = -1 or 1 <= ti <= 100).

输出描述:

Output a single integer, the number of different days Tomori could have experienced. Since the answer might be too large, output it modulo 1000000007.

示例1

输入

复制

3
-1 2 1

输出

复制

3

说明

There are 6 possible permutations.

If p = {1, 2, 3}, then b = {-1, 2, 1}.

If p = {1, 3, 2}, then b = {-1, 2, 1}.

If p = {2, 1, 3}, then b = {3, 2, 1}.

If p = {2, 3, 1}, then b = {2, 2, 1}.

If p = {3, 1, 2}, then b = {3, 2, 1}.

If p = {3, 2, 1}, then b = {2, 2, 1}.

There are 3 distinct possible days Tomori could have experienced.

Please note that even if we have b = {1, 2, 2} with some permutation, it is considered the same as b = {2, 2, 1}, since Tomori can't distinguish between her friends.

#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const int mod = 1e9 + 7;
int dp[N][N][N];
int tim[N], sum[N];
int main() {
    ios::sync_with_stdio(0);
    int n; cin >> n;
    for (int i = 1; i <= n; i++) {
        int t; cin >> t;
        if (t != -1)tim[t]++;
    }
    for (int i = 1; i < N; i++){
        sum[i] = tim[i] + sum[i - 1];
    }
    int res = 0;
    dp[0][0][0] = 1;
    for (int i = 1; i < N; i++) {
        for (int j = sum[i]; j <= n; j++) {
            for (int k = 0; k <= j; k++) {
                for (int l = max(0, k - tim[i]); l <= j - k; l++) {
                    dp[i][j][k] += dp[i - 1][j - k][l];
                    dp[i][j][k] %= mod;
                }
                if (j >= sum[N - 1] && k) {//防止状态重复计算
                    res += dp[i][j][k];
                    res %= mod;
                }
            }
        }
    }
    if (sum[N - 1] == 0) res = 1;//特判
    cout << res << "\n";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/chenshibo17/article/details/99674312
今日推荐