zoukankan      html  css  js  c++  java
  • P5299 [PKUWC2018]Slay the Spire

    在最少出一张攻击牌,尽量多的打强化牌,因为它至少让牌翻倍,排序选出最大攻击牌,强化牌不够,再打出较大攻击牌

    (f_{i,j})为考虑了排序后的前 (i) 张强化牌且第 (i) 张必选,选了 (j) 张牌的效果,(g_{i,j})为考虑了排序后的前 (i) 张攻击牌且第 (i) 张必选,选了 (j) 张牌的效果,得:

    [f[i][j]=v_isum_{k=j-1}^{i-1}f[k][j-1]\ g[i][j]={i-1choose j-1}v_i+sum_{k=j-1}^{i-1}g[k][j-1] ]

    考虑(f,g)(F,G)贡献

    [F[i][j]=sum_{k=j}^n{n-kchoose i-j}f[k][j]\ G[i][j]=sum_{k=j}^n{n-kchoose i-j}g[k][j] ]

    #include<cstdio>
    #include<algorithm>
    #define mod 998244353
    using namespace std;
    const int maxn = 3001;
    inline int read() {
    	char c=std::getchar();int x=0;while(c<'0'||x>'9') c=std::getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=std::getchar();return x;
    }
    int c[maxn][maxn],dp[maxn][maxn],f[maxn][maxn];
    int g[maxn][maxn],h[maxn][maxn];
    int n,m,k;
    int a[maxn],b[maxn];
    bool cmp(int a,int b){return a > b;}
    inline int C(int n,int m){return m > n ? 0 : c[n][m];}
    int main(){
    	int T,M=2000;T = read();
    	for(int i = 0;i <= M;i++) c[i][0] = c[i][i] = 1;
    		for(int i = 1;i <= M;i++)
    			for(int j = 1;j < i;j++)
    				c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
    	while(T--){
    		n = read();m = read();k = read();
    		for(int i = 1;i <= n;i++) a[i] = read();
    		for(int i = 1;i <= n;i++) b[i] = read();
    		std::sort(a+1,a+n+1,cmp); std::sort(b+1,b+n+1,cmp);
    		dp[0][0] = 1;
    		for(int i=1;i<=n;i++)
    			for(int j=0;j<=i;j++) {
    				dp[i][j]=dp[i-1][j];
    				if(j) dp[i][j]=(dp[i][j]+1ll*dp[i-1][j-1]*a[i]%mod)%mod;
    			}
    		f[0][0]=1;
    		for(int i=1;i<=n;i++) 
    			for(int j=1;j<=i;j++) 
    				f[i][j]=1ll*dp[i-1][j-1]*a[i]%mod;
    		h[0][0]=0;
    		for(int i=1;i<=n;i++)
    			for(int j=0;j<=i;j++) {
    				h[i][j]=h[i-1][j];
    				if(j) h[i][j]=(h[i][j]+1ll*C(i-1,j-1)*b[i]%mod+h[i-1][j-1])%mod;
    			}
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=i;j++)
    				g[i][j]=(1ll*C(i-1,j-1)*b[i]%mod+h[i-1][j-1])%mod;
    		int ans=0;
    		for(int i=0;i<m;i++) {
    			int now=0;
    			for(int j=0;j<=n;j++) {
    				if(i<=k-1) now=(now+f[j][i])%mod;
    					else now=(now+1ll*f[j][k-1]*C(n-j,i-k+1)%mod)%mod;
    			}
    			int tot=0,res=0;
    			if(i<=k-1) res=k-i;else res=1;
    			for(int j=0;j<=n;j++) 
    				tot=(tot+1ll*g[j][res]*C(n-j,m-i-res)%mod)%mod;
    			ans=(ans+1ll*now*tot%mod)%mod;
    		}
    		printf("%d
    ",ans);
    	}
    } 
    
  • 相关阅读:
    Mac OS X上安装配置apache服务器
    eclipse 发布web工程,修改tomcat端口
    masonry瀑布流的使用
    fullcalendar 使用教程
    -webkit-line-clamp下多行文字溢出点点点...显示实例页面
    HTML5 Audio标签方法和函数API介绍
    Canvas与Image互相转换
    iOS绘图UIBezierPath 和 Core Graphics框架
    实现外卖选餐时两级 tableView 联动效果
    零行代码为 App 添加异常加载占位图
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13502778.html
Copyright © 2011-2022 走看看