洛谷——P1025 数的划分
P1025 数的划分
题目描述
将整数nn分成kk份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:n=7n=7,k=3k=3,下面三种分法被认为是相同的。
$1,1,51,1,5;$
$1,5,11,5,1;$
$5,1,15,1,1.$
问有多少种不同的分法。
输入输出格式
输入格式:
n,kn,k (6<n \le 2006<n≤200,2 \le k \le 62≤k≤6)
输出格式:
11个整数,即不同的分法。
输入输出样例
说明
四种分法为:
$1,1,51,1,5;$
$1,2,41,2,4;$
$1,3,31,3,3;$
$2,2,32,2,3.$
数据小,$dfs$完全可以水过去
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<cmath> #include<algorithm> #define N 110000 #define ll long long #define RE register void read(int &x){ x=0;int flg=1;char ch=getchar(); for(;ch<'0'||ch>'9';) {if(ch=='-') flg=-1;ch=getchar();} for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x=x*flg; } using namespace std; int n,k,ans; void dfs(int last,int sum,int c){ if(c==k){ if(sum==n) ++ans; return; }else{ for(int i=last;sum+i*(k-c)<=n;i++){ dfs(i,sum+i,c+1); } } } int main() { read(n);read(k); dfs(1,0,0); printf("%d",ans); return 0; }
划分型DP
$F[i][j]$表示$i$分成$m$份的方案数
状态转移方程:$F[i][j]=F[i-1][j-1]+F[i-j][j]$
状态转移方程的意义:将$i$分成$j$份,相当于由将$i-1$分成$j-1$份在添加$1$转移过来;并且由将$i-j$划分为$j$份,这$j$份再次每一个都+1,不就变成了$i$了吗。
#include<iostream> #include<cstdio> using namespace std; int n,m,f[205][105]; int main() { scanf("%d%d",&n,&m); f[0][0]=1; for(int i=1;i<=n;i++){ for(int j=1;j<=m&&j<=i;j++){ f[i][j]=f[i-1][j-1]+f[i-j][j]; } } printf("%d\n",f[n][m]); return 0; }
博主蒟蒻,若有出错的地方,敬请指出。
如有侵犯您版权的地方,请快速联系我,我会撤回本博文。