(2.17)划分数

题目(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;
}

猜你喜欢

转载自blog.csdn.net/qq_36321330/article/details/106925125