划分数问题

放苹果

http://www.nowcoder.com/questionTerminal/4f0c1e21010e4d849bde5297148e81d9

https://blog.csdn.net/csyifanZhang/article/details/105652758
↑为了更好的阅读体验

这道题是一个模板题,所以先上原模板:
在这里插入图片描述
这样的划分被称作划分数,特别地,时称作 的划分数、DP不仅对于求解最优问题有效,对于各种排列组合的个数、概率或者期望之类的计算同样很有用。在此,我们定义如下。

根据这一定义可以得到怎样的递推关系呢?将个划分成个的话,可以先取出个然后将剩下的个分成份,这时大家是不是认为也许就可以得到下面的递推式了?
$$

但很不幸的是,这个递推是不正确的。用这个办法的话,例如1+1+2和1+2+1的划分就被当成是不同的划分来计数了。为了不重复计数,我们需要寻找别的递推关系。考虑划分

  • 如果有任意,那么也就是划分此时这两个组合数是一样的,因为前者也只是给后者每个位置+1而已。
  • 如果存在,那么就对应了划分。

而对于而言,这两种可能性显然都可以在他的排列种发生,而如果,那么只有第二种情况会发生。因此我们有

if(j>=i)dp[i][j]=(dp[i-1][j]+dp[i][j-i])\%M

else ~dp[i][j]=dp[i-1][j]

例题:牛客网-放苹果

题目描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入描述:

每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

输出描述:

对输入的每组数据M和N,用一行输出相应的K。

#define ll int
#define vec vector<ll>
#define MAX 15
#define inf 0x3fffffff

ll dp[MAX][MAX];

int main() {
    ll M, N;
    while (cin >> M >> N) {
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        for (int i = 1; i <= N; i++) {
            //j从零开始,也就是每行的第一列都是1 dp[i][0]=1 因为盘子可以为空
            for (int j = 0; j <= M; j++) {
                if (j >= i)dp[i][j] = dp[i - 1][j] + dp[i][j - i];
                else dp[i][j] = dp[i - 1][j];
            }
        }
        cout << dp[N][M] << endl;
    }
}
全部评论

相关推荐

从24年初开学开始接触到前端,和实验室几个同学一起学习,可似乎我总比他们慢一步,每每学完一个地方,我掌握的程度好像都不比他们,第一次实验室的任务实战,我两眼一抹黑,完全不知道从何下手,而他们却是游刃有余,可我当时没有丧气,只有一个念头,既然学习能力不如他们,那我就拿更多的时间去学,于是我把打游戏,运动锻炼的时间也拿来学习。到了暑假,实验室一起做项目,为了可以更好的参与进去,于是我暑假开始留校和同学师哥一起做项目,每天早上九点多去实验室,晚上十点多回宿舍,校田径队的训练没有去,中间也只回家待了一周。到暑假结束开学之后,一位很优秀的师哥拿到了几个offer,我从他身上看到了希望,双非本科就业的希望...
offer求求哩:我的评价是认知低,建议多看书,认知低的一个表现是人生仿佛没考上大学就是进厂,考上了就是考研考公找工作。股市里有一个很有意思的故事,说的是当门口大妈都在谈论股票的时候,说明行情已经见顶了。当你的父母在某些事上没有成功却支持你说明事情可能已经不可靠了,但在某些事上反对你,说明这件事可能还有成功的可能。(仅个人观点)😆😆
点赞 评论 收藏
分享
换个名字Z:我在小红书和牛客刷到不下于5篇自愿无薪实习的(姿态降的像奴才一样),环境就是被这些人搞差的恶而不自知
点赞 评论 收藏
分享
评论
22
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务