DとEの難易度が反転してる。
https://codeforces.com/contest/1606/problem/E
問題
N人の人がおり、それぞれ初期HPをA[i]とする。
1ターン毎に、各人は(残存人数-1)だけHPを減らす。
その結果、HPが0以下になった人は脱落する。
最後1名が残ったらそこで終了とする。
各人のHPが1~Xとなるケースは、X^N通りある。
そのうち、最後1名が残るケースは何通りか。
解法
F(n,x) := n人中最大HPxの人が1人いるようなHPの組み合わせ
とする。1ターン前にHPが1だった人がy人いるとすると、F(n+y,x+n+y-1)→F(n,x)と遷移したことになる。
n,x,yを総当たりしながら、上記遷移を列挙しよう。
int N,X; const ll mo=998244353; ll comb(ll N_, ll C_) { const int NUM_=400001; static ll fact[NUM_+1],factr[NUM_+1],inv[NUM_+1]; if (fact[0]==0) { inv[1]=fact[0]=factr[0]=1; for (int i=2;i<=NUM_;++i) inv[i] = inv[mo % i] * (mo - mo / i) % mo; for (int i=1;i<=NUM_;++i) fact[i]=fact[i-1]*i%mo, factr[i]=factr[i-1]*inv[i]%mo; } if(C_<0 || C_>N_) return 0; return factr[C_]*fact[N_]%mo*factr[N_-C_]%mo; } ll modpow(ll a, ll n = mo-2) { if(a<0) return 0; ll r=1;a%=mo; while(n) r=r*((n%2)?a:1)%mo,a=a*a%mo,n>>=1; return r; } ll dp[505][505]; void solve() { int i,j,k,l,r,x,y; string s; cin>>N>>X; ll ret=0; for(i=2;i<=N;i++) { for(x=1;x<=i-1;x++) { dp[i][x]=(modpow(x,i)-modpow(x-1,i)+mo)%mo; } for(x=1;x<=X;x++) { for(int add=0;i+add<=N;add++) { if(x+(i+add-1)>X) continue; (dp[i+add][x+(i+add-1)]+=dp[i][x]*comb(i+add,i)%mo*modpow(i+add-1,add))%=mo; } if(i==N) { ret+=dp[N][x]; } } } cout<<ret%mo<<endl; }
まとめ
DとE逆で良かったかもね。