【划分型DP】整数划分

    xiaoxiao2025-06-02  31

    作为划分型DP中的基础题,在今天也算是完成了,对DP的用法也渐渐明朗起来。 题目描述 Description

    将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序)。 例如:n=7,k=3,下面三种划分方案被认为是相同的。 1 1 5

    1 5 1

    5 1 1 问有多少种不同的分法。

    输入描述 Input Description

    输入:n,k (6<n<=200,2<=k<=6)

    输出描述 Output Description

    输出:一个整数,即不同的分法。

    样例输入 Sample Input

     7 3

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

     {四种分法为:1,1,5;1,2,4;1,3,3;2,2,3;}

    本题的状态转移方程为: d[i][j]=d[i-j][j]+d[i-1][j-1],dp[i][j]代表i分成j个部分有几种分法

    推导过程如下:

    原先,转移方程是 dp[i,j]:=dp[i-j,1]+dp[i-j,2]+dp[i-j,3]+…+dp[i-j,j-1]+dp[i-j,j]; 由于, dp[i,j]=dp[i-j,1]+dp[i-j,2]+…+dp[i-j,j]; dp[i-1,j-1]=dp[(i-1)-(j-1),1]+dp[(i-1)-(j-1),2]+…+dp[(i-1)-(j-1),j-1] = dp[i-j,1]+dp[i-j,2]+…+dp[i-j,j-1];

    由此推出

    dp[i,j]=dp[i-j,1]+dp[i-j,2]+…+dp[i-j,j-1]+dp[i-j,j] =dp[i-1,j-1]+dp[i-j,j];

    代码如下:

    #include<iostream> using namespace std; int d[1000][10], n, k; int main() { cin >> n >> k; d[0][0] = 1; for (int i = 1; i <= n; i++) d[i][1] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= k; j++) if (i >= j) d[i][j] = d[i - j][j] + d[i - 1][j - 1]; cout << d[n][k]<<endl; return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-1299525.html
    最新回复(0)