hihocoder-Weekly221-Push Button II
题目1 : Push Button II
描述
There are N buttons on the console. Each button needs to be pushed exactly once. Each time you may push several buttons simultaneously.
Assume there are 4 buttons. You can first push button 1 and button 3 at one time, then push button 2 and button 4 at one time. It can be represented as a string "13-24". Other pushing way may be "1-2-4-3", "23-14" or "1234". Note that "23-41" is the same as "23-14".
Given the number N your task is to find the number of different valid pushing ways.
输入
An integer N. (1 <= N <= 1000)
输出
Output the number of different pushing ways. The answer would be very large so you only need to output the answer modulo 1000000007.
- 样例输入
-
3
- 样例输出
-
13
简单的DP问题
将 dp[i][j] 定义为 i 个button 分为 j 个顺序的种类, 那么:
dp[i][j] 可以由前一个状态转移得到, dp[i][j] = j * dp[i-1][j] + j * dp[i][j-1]
其中 j * dp[i-1][j] 表示为 将第i个放入 含有1- (i-1) 的j 堆中,其中 i 可以放入j 中任意一组,种类为 j
其中 j * dp[i][j-1] 表示为 第i个单独出来,形成第 j堆,那么整个新堆可以插入上面的次序中,一种j种插入方式。
#include <cstdio> #include <cstring> #include <cstdlib> const int MAXN = 1000 + 10; const long long mod = 1000000007; int n; long long dp[MAXN][MAXN]; int main(){ while(scanf("%d", &n) != EOF) { memset(dp, 0, sizeof(dp)); dp[1][1] = 1; for(int i=2; i<=n; ++i) { for(int j=1; j<=i; ++j) { dp[i][j] = (j * dp[i-1][j] + j*dp[i-1][j-1]) % mod; } } long long ans = 0; for(int i=1; i<=n; ++i){ ans += dp[n][i]; } printf("%lld ", ans%mod ); } return 0; }