• CF1606E


    CF1606E

    题目大意:给定(n,x(n,xle500)),代表有(n)个人,每个人初始的血量在(1-x)之间,每一轮每一个活着的人会对其他活着的人(除了自己)造成一点伤害,求有多少种初始局面使得最终所有人都会死掉,对998244353

    首先这个数据范围和题目第一反应都是DP考虑一下DP, 状态记录的是必要的信息,每一轮的伤害是和当前人数直接挂钩的,所以需要记录当前剩余人数.也就是说每一次转移都会考虑当前要死几个人,那么为了方便死的人的血量的计算,所以当前已经收到的伤害也是要记录的

    (f_{i,j})表示还剩下(i)人,活着的人每人收到了(j)点伤害的方案数

    每次枚举这一轮死掉的人数,那么死掉的人的血量就应该处于(j + 1)(max(x,j+i-1))之间

    转移方程式

    [f_{k,max(j+i-1,x)}=f_{i,j} * C_i^k*(i-k)^{max(x,j+i-1)-j} ]

    当然为了满足最后所有人都死亡的条件

    最多转移到(i >= 2)

    最后(f_{0,i})的和就是所求

    #include<bits/stdc++.h>
    #define LL long long
    #define mk make_pair
    #define pii pair<int,int>
    #define fi first
    #define se second
    using namespace std;
    const int N = 505;
    const LL mod = 998244353;
    LL fac[N],inv[N],f[N][N];
    int n,k,h;
    LL tt[N][N];
    inline int read(){
    	int v = 0,c = 1;char ch = getchar();
    	while(!isdigit(ch)){
    		if(ch == '-') c = -1;
    		ch = getchar();
    	}
    	while(isdigit(ch)){
    		v = v * 10 + ch - 48;
    		ch = getchar();
    	}
    	return v * c;
    }
    inline LL quick(LL x,LL y){
    	LL res = 1;
    	while(y){
    		if(y & 1) res = res * x % mod;
    		y >>= 1;
    		x = x * x % mod;
    	}
    	return res;
    }
    inline LL C(int x,int y){
    	return fac[x] * inv[y] % mod * inv[x - y] % mod;	
    }
    int main(){
    	n = read(),h = read();
    	fac[0] = 1,inv[0] = 1;
    	for(int i = 1;i <= 500;++i) fac[i] = fac[i - 1] * i % mod;
    	inv[500] = quick(fac[500],mod - 2);
    	for(int i = 500 - 1;i >= 1;--i) inv[i] = inv[i + 1] * (i + 1) % mod;
    	for(int i = 1;i <= 500;++i){
    		for(int j = 0;j <= 500;++j) tt[i][j] = quick(i,j);	
    	}
    	f[n][0] = 1;
    //	printf("%lld
    ",C(5,3));
    	for(int i = n;i >= 2;--i){
    		for(int j = 0;j <= h;++j){
    			for(int k = i;k >= 0;--k){
    				
    				int t = min(h,j + i - 1);
    				f[k][t] = (f[k][t] + f[i][j] * C(i,k) % mod * tt[t - j][i - k]) % mod;
    			//	printf("from:%d %d to:%d %d %lld
    ",i,j,k,t,f[k][t]);	
    			}
    		}
    	}
    	LL ans = 0;
    	for(int i = 0;i <= h;++i) ans += f[0][i];
    	printf("%lld
    ",ans % mod);
        return 0;
    }
     
    
  • 相关阅读:
    txt换行追加写入
    np.unique( )的用法
    生成自己想要的任意颜色的图片
    183. 木材加工
    575. 字符串解码
    364. 接雨水 II
    255. Multi-string search
    433. 岛屿的个数
    591. 连接图 III
    918. 三数之和
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/15514031.html
Copyright © 2020-2023  润新知