1 solutions
-
2
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
勿喷! 完结!
给个好评~
Information
- ID
- 602
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 34
- Accepted
- 10
- Uploaded By