zoukankan      html  css  js  c++  java
  • [LOJ #2538][PKUWC 2018]Slay the Spire

    题目大意:一开始有 $2n$ 张牌,每张牌上都写着一个数字 $w_i$,有两种的牌,每种类型各 $n$ 张:

    1.攻击牌:打出后对对方造成牌上的数字的伤害。

    2.强化牌:打出后,设数字为 $x$,则其他剩下的攻击牌的数字都会乘上 $x$。保证强化牌上的数字都大于$1$。

    现在会等概率随机从卡组中抽出 $m$ 张牌,但最多打出 $k$ 张牌,假设会采取能造成最多伤害的策略,求她期望造成多少伤害。

    题解:发现有若可以的话,先从大到小打强化牌,再从大到小打攻击牌(至少打一张),这样会造成最大伤害,然后我就不会了。。。

    卡点:

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #define maxn 3010
    #define int long long
    using namespace std;
    const int mod = 998244353;
    int Tim, n, m, k;
    int a[maxn], b[maxn];
    int fac[maxn], inv[maxn];
    int f[maxn][maxn], g[maxn][maxn];
    int sf[maxn][maxn], sg[maxn][maxn];
    inline bool cmp(int a, int b) {return a > b;}
    int C(int a, int b) {
    	if (b > a) return 0;
    	return fac[a] * inv[b] % mod * inv[a - b] % mod;
    }
    int F(int a, int b) {
    	if (a < b) return 0;
    	int ans = 0;
    	for (int i = 0; i <= n; i++) ans = (ans + f[b][i] * C(n - i, a - b)) % mod;
    	return ans;
    }
    int G(int a, int b) {
    	if (a < b) return 0;
    	int ans = 0;
    	for (int i = 0; i <= n; i++) ans = (ans + g[b][i] * C(n - i, a - b)) % mod;
    	return ans;
    }
    signed main() {
    	fac[0] = fac[1] = inv[0] = inv[1] = 1;
    	for (int i = 2; i <= maxn; i++) {
    		fac[i] = fac[i - 1] * i % mod;
    		inv[i] = inv[mod % i] * (mod - mod / i) % mod;
    	}
    	for (int i = 2; i <= maxn; i++) inv[i] = inv[i] * inv[i - 1] % mod;
    	scanf("%lld", &Tim);
    	while (Tim --> 0) {
    		scanf("%lld%lld%lld", &n, &m, &k);
    		for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    		sort(a + 1, a + n + 1, cmp);
    		f[0][0] = 1;
    		for (int i = 0; i <= n; i++) sf[0][i] = 1;
    		for (int i = 1; i <= n; i++) {
    			for (int j = 1; j <= n; j++) {
    				f[i][j] = a[j] * sf[i - 1][j - 1] % mod;
    				sf[i][j] = (sf[i][j - 1] + f[i][j]) % mod;
    			}
    		}
    		for (int i = 1; i <= n; i++) scanf("%lld", &b[i]);
    		sort(b + 1, b + n + 1, cmp);
    		for (int i = 1; i <= n; i++) {
    			for (int j = 1; j <= n; j++) {
    				g[i][j] = (b[j] * C(j - 1, i - 1) + sg[i - 1][j - 1]) % mod;
    				sg[i][j] = (sg[i][j - 1] + g[i][j]) % mod;
    			}
    		}
    		int ans = 0;
    		for (int i = 0; i <= m; i++) {
    			if (i < k) ans = (ans + F(i, i) * G(m - i, k - i)) % mod;
    			else ans = (ans + F(i, k - 1) * G(m - i, 1)) % mod;
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    vsftpd的主动模式与被动模式
    Linux环境下vsftpd参数配置
    CentOS下的网络配置文件说明
    第一篇博客,随笔留念
    asp.net xml 增删改操作
    asp.net json 与xml 的基础事例
    linq 之 Distinct的使用
    【P2015】二叉苹果树(树状DP)
    【P2016】战略游戏(贪心||树状DP)
    【P2774】方格取数问题(贪心+最大流,洛谷)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9474706.html
Copyright © 2011-2022 走看看