5195. 【NOIP2017提高组模拟7.3】A (Standard IO)

时间:2022-12-17 14:18:00

Description

 

我们有n个相同的弹珠,k个相同的盒子。现在随机的将每个弹珠扔进盒子中,使得最终每个盒子非空,求出一共有多少种不同的方案。两种方案不同当且仅当将盒子中的弹珠数最小表示后不同。由于方案数可能非常多,出题人又良心的不让你们写高精度,把答案摸998244353输出即可。

 

Input

第一行输入两个正整数n,k。
 
 

Output

 
输出共一行,一个整数表示Ans mod 998244353的值 
 

Solution

以下皆为100分方法,皆可AC。

方法一:

类似第二类????????????????????????????????数的,我们将方案分成两种:

1.至少包含一个 1 的;          

 2.一个 1 都不包含。

设????[????][????]表示答案,那么表示1.的答案即为????[???? − 1][???? − 1],

表示2.的答案 即为????[???? − ????][????](相当于把每个数都加上1),

所以有: ????[????][????] = ????[???? − 1][???? − 1] + ????[???? − ????][????],时间O(????????)。

 

方法二:

如图:

5195. 【NOIP2017提高组模拟7.3】A (Standard IO)

可找到规律,设n=0,k=1是结果为1,

则第n行第k列=第(n-k)行第一列到第k列的和。

 

代码

方法一:

 1 const  2 mo=998244353;  3 var  4  n,k:longint;  5 f:array [0..5001,0..5001] of longint;  6 function min(o,p:longint):longint;  7 begin  8 if o<p then exit(o);  9  exit(p); 10 end; 11 12 procedure main; 13 var 14  i,j:longint; 15 begin 16 f[0,0]:=1; 17 for i:=1 to n do 18 for j:=1 to min(i,k) do 19 f[i,j]:=(f[i-1,j-1]+f[i-j,j]) mod mo; 20 end; 21 22 begin 23  readln(n,k); 24  main; 25  writeln(f[n,k]); 26 end.

方法二:

 

const mo=998244353; var n,k:longint; sum:array [0..5001] of longint; f:array [0..5001,0..5001] of longint; procedure main; var i,j:longint; begin for i:=0 to 5000 do begin f[i,1]:=1; sum[i]:=1; end; for i:=2 to 5000 do begin for j:=i to 5000 do f[j,i]:=(sum[j-i]+f[j-i,i]) mod mo; for j:=i to 5000 do sum[j]:=(sum[j]+f[j,i]) mod mo; end; end; begin readln(n,k); main; writeln(f[n,k]); end.