题意:
上一周Pushbutton I题目链接 修改版,输入n范围变成1000,问满足条件的数量,不要求输出搜索过程。那么这题从搜索题变成常见动态规划问题。定义dp[i][j]表示i个数分成j组的数量。
递推式是什么呢?简单思考一下:
举例 dp[3][2]
情况有 : 可以从dp[2][1] :1 2
加一个分组 3成为1 2 -3
或者dp[2][2]: 1-2 or 2-1
加入3 成为 1-23 or 2-13
。再仔细思考发现, 这里面每个分组的顺序都可以和新的分组交换形成新的可能比如:12-3
中 12和 3交换一下 3-12
又是一个新的序列。
所以递推式是: dp[i][j] = dp[i-1][j-1]*j + dp[i-1][j]*j
最后注意计算中间过程会溢出,需要取long long 。
样例:
样例输入
3
样例输出
13
思路:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010,mod = 1000000007;
long long dp[maxn][maxn];
long long sum[maxn];
void init(){
memset(dp,0,sizeof(dp));
dp[1][1] = 1;
for(int i=2;i<=1000;i++){
for(int j=1;j<=i;j++){
dp[i][j] = (j*dp[i-1][j-1]%mod + j*dp[i-1][j]%mod)%mod;
}
}
for(int i=1;i<=1000;i++){
sum[i] = 0;
for(int j=1;j<=i;j++){
sum[i] = (sum[i] + dp[i][j])%mod;
}
}
}
int main(){
int n;
init();
while(~scanf("%d",&n)){
printf("%d\n",sum[n]);
}
}