I. Space Station (hash memory + dp)

"Articles" by Lu You The
article is a natural success, and it happens occasionally.
It's so flawless, it doesn't need to be artificial.
When you look at the ancient Yi artifacts, you can do nothing with cleverness.
The Han Dynasty has recently been pre-Qin Dynasty, and it has been very sincere.
What is the Hu family?
Who will meet the deadline for thousands of years?

I. Space Station

Big brother problem solution The
above problem solution is very good! Thoughts are progressive, and the Hornet praised

Violence: First sort the original array, then dfs enumerate the selection order, if the current sum has ≥ 50 \ge50. 5 0 can be calculated using the factorial of the number of programs,the complexity can not be calculated

Memory search: How to memorize search is involved here?
Positive solutions are very clever, because ai a_iaiThe range of is very small, here only the number of occurrences of each value is recorded, this information is enough to restore the necessary information of the original array.

The most ingenious is hash memory, when all the remaining numbers are the same, the number of schemes is the same. Here the array of recorded times is hashed, then the memoization is completed! ! !

If you think of the above, it still doesn’t work. TLE still doesn’t get stuck. QQ
notices that if ai=0 a_i=0ai=0 We can choose him at any time, that is, its choice is not constrained, so we can eliminate 0 first, and finally count 0’s contribution to the answer directly.
Our choice is a sorting. Just insert these 0s into the selection process. The final answer needs to be multiplied by (cnt + 1) × (cnt + 2) ×… × n (cnt+1)×(cnt+ 2)×\dots×n(cnt+1)×(cnt+2)××n
cnt is the number of non-zero numbers

#include<unordered_map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=100010,mod=1e9+7;
const ull P=131;
int n;
int a[55];
ll fact[N];
unordered_map<ull,ll> dp;
void init()
{
    
    
    fact[0]=1;
    for(int i=1;i<=100000;i++) fact[i]=fact[i-1]*i%mod;
}
ll dfs(int u,int now)
{
    
    
    if(!u) return 1;
    if(now>=50) return fact[u];
    ull hash=0;
    for(int i=50;i;i--) hash=hash*P+a[i];
    if(dp[hash]) return dp[hash];
    
    ll res=0;
    for(int i=1;i<=now;i++)
    {
    
    
        if(!a[i]) continue;
        a[i]--;
        res=(res+(a[i]+1)*dfs(u-1,now+i)%mod)%mod;
        a[i]++;
    }
    return dp[hash]=res;
}
int main()
{
    
    
    init();
    int now;
    cin>>n>>now;
    int cnt0=0,cnt1=0;
    for(int i=1;i<=n;i++)
    {
    
    
        int x;
        cin>>x;
        if(!x) cnt0++;
        else a[x]++,cnt1++;
    }
    ll ans=dfs(cnt1,now);
    for(int i=n;i>=cnt1+1;i--)
        ans=(ans*i)%mod;
    cout<<ans<<'\n';
    return 0;
}

The first time I saw hash memory, it was very clever! ! ! Practice more dishes, or
you will always hang up during training .

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/112501591