Loading

CF1606E Arena

\(f_{i, j}\) 为目前有 \(i\) 个人,血量最高为 \(j\) 的方案数。那么我们 DP 就是在倒着做这个过程,每次枚举新增几个人即可。

代码:

#include <bits/stdc++.h>

using namespace std;
 
#define int long long
#define fir first
#define sec second
#define mkp make_pair 
#define pb push_back
#define lep( i, l, r ) for ( int i = ( l ); i <= ( r ); ++ i )
#define rep( i, r, l ) for ( int i = ( r ); i >= ( l ); -- i )
 
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair < int, int > pii;
 
namespace IO{
	const int SIZE=1<<21;
	static char ibuf[SIZE],obuf[SIZE],*iS,*iT,*oS=obuf,*oT=oS+SIZE-1;
    int qr;
    char qu[55],c;
    bool f;
	#define getchar() (IO::iS==IO::iT?(IO::iT=(IO::iS=IO::ibuf)+fread(IO::ibuf,1,IO::SIZE,stdin),(IO::iS==IO::iT?EOF:*IO::iS++)):*IO::iS++)
	#define putchar(x) *IO::oS++=x,IO::oS==IO::oT?flush():0
	#define flush() fwrite(IO::obuf,1,IO::oS-IO::obuf,stdout),IO::oS=IO::obuf
	#define puts(x) IO::Puts(x)
	template<typename T>
    inline void read(T&x){
    	for(f=1,c=getchar();c<48||c>57;c=getchar())f^=c=='-';
    	for(x=0;c<=57&&c>=48;c=getchar()) x=(x<<1)+(x<<3)+(c&15); 
    	x=f?x:-x;
    }
    template<typename T>
    inline void write(T x){
        if(!x) putchar(48); if(x<0) putchar('-'),x=-x;
        while(x) qu[++qr]=x%10^48,x/=10;
        while(qr) putchar(qu[qr--]);
    }
    inline void Puts(const char*s){
    	for(int i=0;s[i];i++)
			putchar(s[i]);
		putchar('\n');
	}
	struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}
using IO::read;
using IO::write;
 
template < class type > inline void chkmin ( type &x, type y ) { x = ( x <= y ? x : y ); }
template < class type > inline void chkmax ( type &x, type y ) { x = ( x >= y ? x : y ); }

const int N = 505;
const int mod = 998244353;

int n, m, ans;
int f[N][N], C[N][N];

int fast_pow ( int a, int b ) {
  int res = 1;
  while ( b ) {
    if ( b & 1 ) {
      res = res * a;
      res %= mod;
    }
    b >>= 1;
    a = a * a;
    a %= mod;
  }
  return res;
}

void Solve () {
  cin >> n >> m;
  C[0][0] = 1;
  for ( int i = 1; i <= 500; i ++ ) {
    C[i][0] = 1;
    for ( int j = 1; j <= i; j ++ ) {
      C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
      C[i][j] %= mod;
    }
  }
  for ( int i = 2; i <= n; i ++ ) {
    for ( int j = 1; j <= m; j ++ ) {
      if ( j < i ) {
        f[i][j] = fast_pow ( j, i ) - fast_pow ( j - 1, i );
        f[i][j] %= mod;
      }
      else {
        for ( int k = 1; k <= i; k ++ ) {
          f[i][j] += f[k][j - i + 1] * C[i][k] % mod * fast_pow ( i - 1, i - k ) % mod;
          f[i][j] %= mod;
        }
      }
    }
  }
  for ( int i = 1; i <= m; i ++ ) {
    ans += f[n][i];
    ans %= mod;
  }
  cout << ( ans % mod + mod ) % mod;
}

signed main () {
#ifdef judge
  freopen ( "Code.in", "r", stdin );
  freopen ( "Code.out", "w", stdout );
  freopen ( "Code.err", "w", stderr );
#endif
  Solve ();
	return 0;
}
posted @ 2025-11-13 20:16  Alexande  阅读(4)  评论(0)    收藏  举报