1 solutions

  • 2
    @ 2024-10-24 18:23:28

    F1:DFS剪枝

    1.在dfs中模拟进一步选择的分出的now,直到分出1,再用计数器统计总方案数。

    2.剪枝在如下代码中呈现。

    有一个不得不做的剪枝就是枚举当前划分所用分数时应该从​last​(上次划分所用分数)枚举到sum+i*(k-cur)<=n为止,因为之后划分的分数一定大于或等于当前划分所用分数。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,cnt;
    
    void dfs(int last,int sum,int cur)
    {
        if(cur==k)
        {
            if(sum==n) cnt++;
            return;
        }
        for(int i=last;sum+i*(k-cur)<=n;i++)
            dfs(i,sum+i,cur+1);
    }
    
    int main()
    {
        cin>>n>>k;
        dfs(1,0,0);
        cout<<cnt;
    CEqwq
    

    F2:DP动态规划

    f[i][x] 表示 i 分成 x 个非空的数的方案数。

    显然 i<x 时 f[i][x]=0 , i=x 时 f[i][x]=1;

    其余的状态,我们分情况讨论:

    ①有1的 ②没有1的

    第一种情况,方案数为 f[i-1][x-1]

    第二种情况,方案数为 f[i-x][x] (此时 i 必须大于 x)

    所以,状态转移方程为: f[i][x]=f[i-1][x-1]+f[i-x][x]

    程序如下:

    #include<bits/stdc++.h>
    using namespace std;
    const N=1e4+5
    int n,k,f[N][N]; 
    int main() {
       for(int i=1;i<=n;i++)
            f[i][1]=1;
       for(int i=1;i<=n;i++)
         for(int j=2;j<=k;j++)
             if(i>=j)f[i][j]=f[i-1][j-1]+f[i-j][j];
       cout<<f[n][k];
    CEqwq
    

    勿喷! 完结!


    给个好评~

    • @ 2024-10-24 19:46:04

      总的来说分为两个方法

      一个递归

      一个递推

Information

ID
602
Time
1000ms
Memory
256MiB
Difficulty
7
Tags
# Submissions
34
Accepted
10
Uploaded By