【题解】P1025 数的划分
题面
前言
递推 T3,应用题(很典,可以双倍经验!)
爆搜可以卡过去,亲测
代码来一发:
点击查看代码
#include<iostream>
using namespace std;
int n,k,ans;
void dfs(int x,int s,int t){
if(s==1){
ans++;
return;
}
for(int i=x;i<=t/s;i++){
dfs(i,s-1,t-i);
}
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
dfs(1,k,n);
cout<<ans<<endl;
return 0;
}
正文
状态是容易设置的,$ f_{i,j} $ 表示 $ i $ 拆分成 $ j $ 个数的方案数
考虑转移
把 $ j $ 个数看做 $ j $ 个桶
-
如果 $ j $ 个桶中不包含大小为 $ 1 $ 的桶,有 $ f_{i,j}=f_{i-j,j} $
-
如果 $ j $ 个桶中包含大小为 $ 1 $ 的桶,有 $ f_{i,j}=f_{i-1,j-1} $
合并两种情况,有 $ f_{i,j}=f_{i-1,j}+f_{i-j,j} $
答案即 $ f_{n,k} $
注意初始化即可!
代码
#include<iostream>
using namespace std;
const int maxn=210,maxk=10;
int n,k,f[maxn][maxk];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++){
f[i][1]=1;
f[i][0]=1;
}
for(int i=2;i<=k;i++){
f[1][i]=0;
f[0][i]=0;
}
for(int i=2;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];
}else{
f[i][j]=f[i-1][j-1];
}
}
}
cout<<f[n][k]<<endl;
return 0;
}
后记
很典的题,需熟练掌握!
完结撒花!