loj#2538. 「PKUWC 2018」Slay the Spire【期望dp】

传送门

解题思路:

做这道题时一定要静下心来思考,不能慌……

假设摸到 i 张强化牌, m i 张攻击牌。
首先发现强化牌数值都大于1,所以有一个显然的结论,强化牌能用就用,即:
i < k ,用 i 张强化牌, k i 张最大的攻击牌;
i k ,用 k 1 张强化牌和最大的攻击牌;
那么先把牌从大到小排, f i , j 表示前 i 张强化牌摸了 j 张能翻的倍数和, g i , j 类似。
统计答案时枚举用的张数和断点(因为要用较大的牌,肯定在前面),后面摸了但没用的乘以组合数即可。(其实这是细节最多,最需要想的一步)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
    ll i=0,f=1;char c;
    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
    if(c=='-')c=getchar(),f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}
const int N=3005,mod=998244353;
int n,m,k;
ll ans,a[N],b[N],c[N][N],f[N][N][2],g[N][N][2];
inline bool cmp(const int &a,const int &b){return a>b;}
void solve()
{
    n=getint(),m=getint(),k=getint(),ans=0;
    for(int i=1;i<=n;i++)a[i]=getint();
    for(int i=1;i<=n;i++)b[i]=getint();
    sort(a+1,a+n+1,cmp),sort(b+1,b+n+1,cmp);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            f[i][j][0]=g[i][j][0]=f[i][j][1]=g[i][j][1]=0;
    f[0][0][1]=1;
    for(int i=1;i<=n;i++)
        for(int j=0;j<=n;j++)
        {
            f[i][j][0]=(f[i-1][j][0]+f[i-1][j][1])%mod;
            if(j)f[i][j][1]=(f[i-1][j-1][0]+f[i-1][j-1][1])*a[i]%mod;
            g[i][j][0]=(g[i-1][j][0]+g[i-1][j][1])%mod;
            if(j)g[i][j][1]=(g[i-1][j-1][0]+g[i-1][j-1][1]+c[i-1][j-1]*b[i])%mod;
        }
    for(int i=0;i<m;i++)
    {
        int j=m-i;
        if(i<k)
        {
            for(int l=k-i;l<=n-(m-k);l++)
                ans=(ans+(f[n][i][0]+f[n][i][1])*g[l][k-i][1]%mod*c[n-l][m-k])%mod;
        }
        else
        {
            ll tmp=0;
            for(int l=1;l<=n;l++)tmp=(tmp+b[l]*c[n-l][m-i-1])%mod;
            for(int l=k-1;l<=n-(i-k+1);l++)ans=(ans+f[l][k-1][1]*c[n-l][i-k+1]%mod*tmp)%mod;
        }
    }
    cout<<ans<<'\n';
}
int main()
{
    //freopen("lx.in","r",stdin);
    for(int i=0;i<N;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=i;j++)
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    }
    for(int T=getint();T;T--)solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cdsszjj/article/details/80491860
今日推荐