题目(DP)
代码
n的m划分问题:
dp[i][j] := j的i划分数
将j分划为i个,先取k个,将剩下的j-k分为i-1份
此时的递推式为:
但是,这种方法会把 1+1+2 和 1+2+1的划分就被当成两种划分了,我们需要寻求别的递推关系
设n的m划分为a[i],a[1]+a[2]+…a[m] == n, 如果对于每个i都有a[i] > 0, 那么{a[i] -1}对应了n-m的m划分。如果存在a[i] =0,这对应了n的m-1划分。
递推关系如下:
dp[i][j] = dp[i][j-i] + dp[i-1][j] O(nm)
在解决类似重复计算问题的时候,要小心
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_N = 1000;
const int MAX_M = 1000;
int dp[MAX_M+1][MAX_N+1]; // DP数组
//输入
int n = 4;
int m = 3;
int M = 10000;
void solve(){
dp[0][0] = 1;
for(int i = 1 ; i <= m ; i ++){
for(int j = 0 ; j <= n ; j ++){
if(j-i >= 0)
dp[i][j] = (dp[i-1][j] + dp[i][j-i]) % M;
else
dp[i][j] = dp[i-1][j];
}
}
printf("%d\n", dp[m][n]);
}
int main(){
solve();
return 0;
}