• 「PKUWC2018」Slay the Spire


    题面

    题解

    $ ext{PKUWC2018}$就是$mod;998244353$场。。。

    首先可以发现,应该先打完强化牌后再打攻击牌,牌都尽量打大的。

    所以,打$K−1$张强化,$1$ 张攻击是最优的。当然如果强化用完了就打攻击。

    设$F(x,y)$表示抽出$x$张强化,前$y$张的乘积和

    类似的设$G(x,y)$

    令$f(i,j)$表示用$i$张强化,最小值为$j$的贡献

    类似的设$g(x,y)$

    $ ext{O}(n^2)$求出以上函数即可。

    (不是我说,真的恶心)

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define RG register
    #define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
    #define clear(x, y) memset(x, y, sizeof(x));
    
    namespace IO
    {
    	const int BUFSIZE = 1 << 20;
    	char ibuf[BUFSIZE], *is = ibuf, *it = ibuf;
    	inline char getchar() { if (is == it) it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin); return *is++; }
    }
    
    inline int read()
    {
    	int data = 0, w = 1;
    	char ch = IO::getchar();
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = IO::getchar();
    	if(ch == '-') w = -1, ch = IO::getchar();
    	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = IO::getchar();
    	return data*w;
    }
    
    const int maxn(3010), Mod(998244353);
    int T, n, m, K, a[maxn], b[maxn], C[maxn][maxn];
    int f[maxn][maxn], g[maxn][maxn], sum[maxn][maxn];
    
    int F(int x, int y)
    {
    	if(x < y) return 0;
    	if(!y) return C[n][x];
    	int ans = 0;
    	for(RG int i = x - y + 1; i <= n - y + 1; i++)
    		ans = (ans + 1ll * C[i - 1][x - y] * f[y][i] % Mod) % Mod;
    	return ans;
    }
    
    int G(int x, int y)
    {
    	if(x < y) return 0;
    	int ans = 0;
    	for(RG int i = x - y + 1; i <= n - y + 1; i++)
    		ans = (ans + 1ll * C[i - 1][x - y] * g[y][i] % Mod) % Mod;
    	return ans;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
    	file(cpp);
    #endif
    	for(RG int i = 0; i <= 3000; i++)
    	{
    		C[i][0] = 1;
    		for(RG int j = 1; j <= i; j++)
    			C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % Mod;
    	}
    	T = read();
    	while(T--)
    	{
    		n = read(), m = read(), K = read();
    		for(RG int i = 1; i <= n; i++) a[i] = read();
    		for(RG int i = 1; i <= n; i++) b[i] = read();
    		std::sort(a + 1, a + n + 1);
    		std::sort(b + 1, b + n + 1);
    		for(RG int i = 0; i <= n; i++)
    			for(RG int j = 0; j <= n; j++) f[i][j] = g[i][j] = 0;
    		for(RG int i = 1; i <= n; i++)
    			f[1][i] = a[i], sum[1][i] = (sum[1][i - 1] + a[i]) % Mod;
    		for(RG int i = 2; i <= n; i++)
    		{
    			for(RG int j = 1; j <= n - i + 1; j++)
    				f[i][j] = 1ll * (sum[i - 1][n] -
    					sum[i - 1][j] + Mod) % Mod * a[j] % Mod;
    			for(RG int j = 1; j <= n; j++)
    				sum[i][j] = (sum[i][j - 1] + f[i][j]) % Mod;
    		}
    		for(RG int i = 1; i <= n; i++)
    			g[1][i] = b[i], sum[1][i] = (sum[1][i - 1] + b[i]) % Mod;
    		for(RG int i = 2; i <= n; i++)
    		{
    			for(RG int j = 1; j <= n - i + 1; j++)
    				g[i][j] = (1ll * (sum[i - 1][n] - sum[i - 1][j] + Mod) % Mod
    						+ 1ll * b[j] * C[n - j][i - 1] % Mod) % Mod;
    			for(RG int j = 1; j <= n; j++)
    				sum[i][j] = (sum[i][j - 1] + g[i][j]) % Mod;
    		}
    
    		int ans = 0;
    		for(RG int i = 0; i < m; i++)
    			if(K - 1 <= i) ans = (ans + 1ll * F(i, K - 1)
    					* G(m - i, 1) % Mod) % Mod;
    			else ans = (ans + 1ll * F(i, i) * G(m - i, K - i) % Mod) % Mod;
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    git rebase命令
    java中HashSet对象内的元素的hashCode值不能变化
    Spring中WebApplicationInitializer的理解
    mysql判断表字段或索引是否存在,然后修改
    mysql存储过程
    判断地图上的点是否在圆形,多边形,区域内
    计算任意多边形的面积、中心、重心
    判断点是否在任意多边形内
    springMvc将对象json返回时自动忽略掉对象中的特定属性的注解方式
    String.format()详细用法
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/10203570.html
Copyright © 2020-2023  润新知