• CF1606 E. Arena


    Problem - 1606E - Codeforces

    题意:

    有n个英雄,每一轮每个英雄向除自己之外的所有英雄发动一次攻击

    每个英雄有初始血量,当承受攻击次数>=初始血量时,英雄死亡

    如果最后存在一个英雄活到了最后,他就获胜

    英雄初始血量上限为x

    问有多少种英雄初始血量方案数,满足最后没有获胜的英雄

    dp[i][j]表示现在还有i个英雄,活着的每个英雄已经承受j次攻击,在此情况下已经死亡英雄的初始血量方案数

    设在这一轮攻击之后还剩下k个英雄活着

    那么死亡了i-k个英雄

    在这一轮死亡的英雄的血量至少为j+1,因为他活到了这一轮

    至多为min(x,j+i-1),因为这一轮他承受了i-1次攻击,在这i-1次攻击里他死了,x时初始血量上限

    所以如果一个英雄死在了这一轮,它的初始血量有min(x,j+i-1)- j 种可能

    从i个英雄里选出i-k个死亡,有C(i,i-k)种选法

    令nj=j+i-1

    所以转移为dp[k][nj]+=dp[i][j]*C(i,i-k)*(nj-j)^(i-k)

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int mod=998244353;
    
    #define N 505
    
    int dp[N][N],C[N][N];
    
    int main()
    {
        int n,x;
        scanf("%d%d",&n,&x);
        for(int i=0;i<=n;++i) C[i][0]=1;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
        dp[n][0]=1;
        int nj,pw;
        for(int i=n;i>1;--i)
            for(int j=0;j<x;++j)
            {
                nj=min(j+i-1,x);
                pw=1;
                for(int k=i;k>=0;--k,pw=1ll*pw*(nj-j)%mod)
                    dp[k][nj]=(dp[k][nj]+1ll*dp[i][j]*C[i][i-k]%mod*pw%mod)%mod;
            }
        int ans=0;
        for(int i=1;i<=x;++i) ans=(ans+dp[0][i])%mod;
        printf("%d",ans);     
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    centos下修改hosts
    metasploit rpc
    使用Suricata和ELK进行网络入侵检测
    查询存储设备的UUID
    CentOS基础命令大全
    两个有序数组合并到一个新数组
    dubbo
    redis基本数据类型【3】-List类型
    redis基本数据类型【2】-Hash类型
    redis基本数据类型【1】-String类型
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15534877.html
Copyright © 2020-2023  润新知