【题解】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 $ 个桶

  1. 如果 $ j $ 个桶中不包含大小为 $ 1 $ 的桶,有 $ f_{i,j}=f_{i-j,j} $

  2. 如果 $ 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;
}

后记

很典的题,需熟练掌握!

完结撒花!

posted @ 2024-12-26 16:24  sunxuhetai  阅读(7)  评论(0)    收藏  举报