1 条题解

  • 0
    @ 2026-8-7 23:39:16
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL; 
    LL f[1100][1100];//f[i][j]表示i个球放入j个相同盒子的方案数(允许某些盒子的球数为0) 
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);n-=m;//提前给每个盒子放入1个球 
        memset(f,0,sizeof f);
        for(int i=0;i<=n;i++) f[i][1]=1;//i个球放入1个盒子,只有1种方案 
        for(int j=1;j<=m;j++) f[0][j]=1;//0个球放入j个盒子,只有1种方案 
        for(int i=1;i<=n;i++)
            for(int j=2;j<=m;j++)
            {
            	for(int k=0;k<=i/j;k++)
    				f[i][j]+=f[i-k*j][j-1]; //i个球放入j个盒子,第1个盒子放k个(后面每个盒子都放k个) 
    		}
        printf("%lld",f[n][m]);
        return 0; 
    }
    
    /*
    f[i][j]表示数字i分成j份有几种分法(i个球放进j个盒子)
    f[i][j]=f[i-j][1]+f[i-j][2]………f[i-j][j-1]+f[i-j][j]
    解释:每个盒子放一个球(确保每个盒子都有球),
    剩下的球分成1份或2份或3份……或j份 ,分完叠加到后面的盒子中。
    注意状态转移方程还可以更加优美:
    f[i][j]=f[i-j][1]        +f[i-j][2]………        f[i-j][j-1]+f[i-j][j]  (1式)
    f[i-1][j-1]=f[(i-1)-(j-1)][1]+f[(i-1)-(j-1)][2]………f[(i-1)-(j-1)][j-1]
    因为 (i-1)-(j-1)等于i-j,所以得到
    f[i-1][j-1]=f[i-j][1]+f[i-j][2]………f[i-j][j-1]  (2式)
    把2式代入1式,得到:f[i][j]=f[i-1][j-1]+f[i-j][j]
    
    
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL f[1100][1100]; // f[i][j]表示数字i分成j份有几种分法
    int main()
    {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	memset(f, 0, sizeof f);
    	for (int i = 1; i <= n; i++)
    		f[i][1] = 1;
    	for (int i = 1; i <= n; i++)
    		for (int j = 2; j <= m && j <= i; j++)
    		{
    			if (i == j)
    				f[i][j] = 1;
    			else
    			{
    				for (int k = 1; k <= j && k <= i - j; k++)
    					f[i][j] += f[i - j][k];
    			}
    		}
    	printf("%lld", f[n][m]);
    	return 0;
    }
    */
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL f[1100][1100];
    int main()
    {
    	int n, m;
    	scanf("%d%d", &n, &m);
    	memset(f, 0, sizeof f);
    	for (int i = 1; i <= n; i++)
    		f[i][1] = 1;
    	for (int i = 1; i <= n; i++)
    		for (int j = 2; j <= m && j <= i; j++)
    		{
    			f[i][j] = f[i - 1][j - 1] + f[i - j][j];
    		}
    	printf("%lld", f[n][m]);
    	return 0;
    }
    
    
    • 1

    *【动态规划:状态设计DP】数的划分[NOIP提高组2001]

    信息

    ID
    622
    时间
    1000ms
    内存
    128MiB
    难度
    8
    标签
    递交数
    255
    已通过
    38
    上传者