洛谷P1025数的划分

87 阅读1分钟

 将问题看作:把n个球放入k个盒子,每个盒子至少有一个球,有多少种方法

用dp[n][k]表示方法数

n个球放在k个盒子中,有两种情况

1.存在只有一个球的盒子,则此时方法数就为

dp[n-1][k-1],将一个只有一个球的盒子里的那个球取掉,剩下n-1个球,剩下k-1个盒子

2.Otherwise

即每个盒子至少有两个球

从每个盒子中取出一个球,剩下n-k个球,和k个盒子,方法数为dp[n-k][k]

状态转移方程:dp[n][k]=dp[n-1][k-1]+dp[n-k][k]

初始情况(边界情况):当情况为0个球,0个盒子时,表示所有的球都放完了,所有的盒子都用完了,是一种合法的方法,dp[0][0]=1

#include<iostream>
#include<cstdio>
using namespace std;

int dp[205][10];
int n,k;

int main()
{
    dp[0][0]=1;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=k;j++){
            dp[i][j]=dp[i-1][j-1];
            if(i>=j) dp[i][j]+=dp[i-j][j];
        }
    }

    cout<<dp[n][k]<<"\n";
    return 0;
}