「PKUWC2018」Slay the Spire

International practice and hold casual working

Nonsense

In fact, the title is translated card game on killing minarets, some steam, I was also keen to brush list

answer

First, a desired subject is required false desirable, given in conjunction with the title factorial can be seen and this is actually selected from a $ 2 * n $ $ m $ cards in card use, and takes the maximum value when all cases the

First sort greedy largest

Besides a very obvious conclusion, there is strengthened cards to use, and strengthen the number of cards is greater than 2, it must play to strengthen the brand gains> = ratio play an attacking brand to bring (the last resort must be out at least one attack on the line card)

For example, you have to strengthen the attack cards 22 cards 44 to limit the 2

Then you hit a 2 call and hit a 4 4 4 earnings call as  

So if you want to strengthen the brand Zhang smaller than k, then put all the cards are used to strengthen and finally hit output. If you strengthen brand bigger than k, then the last attack left a card to play out on the line

We can assume that $ F (i, j) $ that you have when i played when j Zhang Zhang strengthen brand benefits, $ G (i, j) $ j sheets that you have to play cards when i return sheets attack

Then the final answer is

$\sum\limits_{i=0}^{k-1} F(i,i)*G(m-i,k-i)+\sum\limits_{i=k}^{k=min(n,m)} F(i,k-1)*G(m-i,1)$

So our task now is to quickly seek out F and G

Consider seeking direct very hard to get, then we usually want to open several other array

First, open the $ f [i] [j] $ $ g [i] [j] $ indicate when you will be drawn to play the first card i i j Zhang Zhang played a total income

You can launch $ f [i] [j] = w_i \ times \ sum f [l] [j-1] $ and $ g [i] [j] = C_ {i-1} ^ {j-1} w_i + \ sum g [l] [j-1] $ (the number of combinations herein represent a total of $ C_ {i-1} ^ {j-1} $ ways transferred from each will be added a transfer w)

Then get $ F (i, j) = \ sum_ {l = j} ^ {n} C_ {nl} ^ {ij} f [l] [j] $

F can be used to explain the j l from Zhang (Zhang are big this j) and then choose not to fight together constitute ij Zhang Zhang F i nl play from the remaining sheets in the j

Similarly to give G $ G (i, j) = \ sum {l = j} ^ {n} C_ {nl} ^ {ij} g [i] [j] $

Then transfer would be finished

This question is often a little card

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1510
#define py printf("f**k\n")
#define mod 998244353
ll n,m,t,k,ans=0,f[1510][1510],g[1510][1510],C[3010][3010],sum1[A],sum2[A],wg[A],wq[A];
inline ll read()
{
    ll x=0; char c=getchar();
    while(isdigit(c)){x=x*10+c-'0' ; C = getchar ();}
     return X; 
} 
LL GCD (X LL, LL Y) { 
    IF (Y == 0 ) return X;
     return GCD (Y, X% Y); 
} 
inline LL F. (LL I , LL J) { 
    LL R & lt = 0 ;
     for (LL L = J; L <= n-; L ++ ) { 
        R & lt = (R & lt + C [NL] [ij of] * F [L] [J]% MOD)% MOD ; // represents the same meaning as the front first l j Double Double selected from nl elect the sheets lj 
    }
     return R & lt; 
} 
inline BOOL CMP ( const LL A &, const LL & B) {
     return a>b;
}
inline ll G(ll i,ll j){
    ll r=0;
    for(ll l=j;l<=n;l++){
        r=(r+C[n-l][i-j]*g[l][j]%mod)%mod;//含义同上
    }
    return r;
}
inline void re(){
    memset(sum1,0,sizeof(sum1));
    memset(sum2,0,sizeof(sum2));
}
inline void init(){
    n=read(),m=read(),k=read();
    f[0][0]=1;
    for(ll i=1;i<=n;i++)
        wq[i]=read();
    sort(wq+1,wq+n+1,cmp);
    for(ll i=1;i<=n;i++)
        wg[i]=read();
    sort(wg+1,wg+n+1,cmp);
    for(ll i=1;i<=n;i++)
        f[i][1]=wq[i],g[i][1]=wg[i];
    for(ll i=1;i<=n;i++){
        for(ll j=2;j<=i;j++){
            sum1[j-1]=(sum1[j-1]+f[i-1][j-1])%mod;
            f[i][j]=wq[i]*sum1[j-1]%mod;
            sum2[j-1]=(sum2[j-1]+g[i-1][j-1])%mod;
            g[i][j]=(C[i-1][j-1]*wg[i]+(sum2[j-1]))%mod;
        }
    }
/*    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=i;j++)
            printf("f[%lld][%lld]=%lld g[%lld][%lld]=%lld\n",i,j,f[i][j],i,j,g[i][j]);
*/}
inline void work(){
    ll ans=0;
    for(ll i=min(n,m);i>=0;i--){
        if(i<k)ans=(ans+F(i,i)*G(m-i,k-i)%mod)%mod/*,printf("F=%lld G=%lld\n",F(i,i),G(m-i,k-i))*/;
        else ans=(ans+F(i,k-1)*G(m-i,1)%mod)%mod/*,printf("F=%lld G=%lld\n",F(i,k-1),G(m-i,1))*/;
//        printf("ans=%lld\n",ans);
    }
    printf("%lld\n",ans);
}
int main()
{
    for(ll i=0;i<=3000;i++)
        C[i][0]=1;
    for(ll i=1;i<=3000;i++)
        for(ll j=1;j<=i;j++)
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    t=read();
    while(t--){
        re();init();work();
    }
}

 

Guess you like

Origin www.cnblogs.com/znsbc-13/p/11238425.html