2 条题解

  • 1
    @ 2026-4-5 17:36:20
    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    const int mod = 1e9 + 7;
    
    int n;
    
    
    int main() {
        cin >> n;
    
        //因为严格递增,所以每个数只能选择一次,那就是从小于等于n的数中选择若干数
        //每个数只能选择一次,最终凑成n的形式,问方案数,因为每个数只能选择一次那就可以用01背包,得到状态数组
        vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
        //dp[i][j]:从前i个数中选取若干数凑成j的总方案数
        dp[0][0] = 1;     //初始化,用于后续递推,且凑成0也为一种方案
    
        for (int i = 1; i <= n; i++)
        {//枚举前i个数
            for (int j = 0; j <= n; j++)
            {//枚举凑成的结果j
                //不选择i:
                dp[i][j] = dp[i - 1][j];
    
                //选择i
                if(j>=i)dp[i][j] = (dp[i][j] + dp[i - 1][j - i]) % mod;
            }
        }
    
        cout << dp[n][n];
    
        return 0;
    }
    
    
    • 1
      @ 2025-5-19 22:20:25

      递归方程为:dp[n][m]= dp[n][m-1]+ dp[n-m][m-1]
      dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。    同样划分情况分为两种情况:   a.划分中每个数都小于m,相当于每个数不大于 m-1,划分数为 dp[n][m-1].   b.划分中有一个数为 m.在n中减去m,剩下相当对n-m进行划分,

      并且每一个数不大于m-1,故划分数为 dp[n-m][m-1] c++代码如下:

      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e3+10,M=1e9+7;
      int f[N][N];
      int main(){
          int n,ans=0;cin>>n;
          f[1][1]=1;
          for(int i=2;i<=n;i++){
              for(int j=2;j<=i;j++){
                  f[i][j]=(f[i-1][j-1]+f[i-j][j-1])%M;
              }
          }
          for(int i=1;i<=n;i++){
              ans=(ans+f[n][i])%M;
          }
          cout<<ans;
      }
      
      • 1

      信息

      ID
      47
      时间
      1000ms
      内存
      256MiB
      难度
      3
      标签
      递交数
      207
      已通过
      71
      上传者