- 数的拆分
- 2024-07-24 09:54:07 @
动规的数组关系式谁能解释一下?
#include<bits/stdc++.h>
using namespace std;
unsigned long long dp[405][405];
int main(){
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++)dp[1][i]=dp[i][1]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i<j)dp[i][j]=dp[i][i];
else if(i==j)dp[i][j]=dp[i][j-1]+1;
else dp[i][j]=dp[i][j-1]+dp[i-j][j];
}
cout<<dp[n][n];
return 0;
}
1 条评论
-
240803gj徐嘉昊 (2212224徐嘉昊) LV 10 @ 2024-07-24 20:15:51
/* 这个dp关系式是指从1~j中选择数字来划分综合为i的数,即dp[i][j]。初始化当总和为1或从1~1中选,都只有一种方案,即1。下面的循环中,若总和小于所选的数,那么继承前面总和为i,从1~i中选数的方案数,因为总和小于所选的数方案为0。如果等于,那么就是比总和为i,从1~j-1中选多一种方案,即i本身。如果大于,这里有点复杂,运用到了完全背包的知识。完全背包原本是三层循环,而其中一层被压缩掉了。那一层循环遍历的是取几件物品。在这题中指1~j这几个数中,每个数你都有无限个,而这层循环遍历的是每个数取几个,即dp[i][j]=dp[i][j-1]+dp[i-j][j-1]+dp[i-j*2][j-1]+...,直到j*n>i为止。但是dp[i-j][j]=dp[i-j][j-1]+dp[i-j*2][j-1]+...(和上面一样),所以dp[i][j]可以优化为dp[i][j-1]+dp[i-j][j]。这个优化是运用在完全背包里面的,我也不知道是谁搞出来的这么牛逼的优化。 */
- 1
信息
- ID
- 1585
- 难度
- 9
- 分类
- (无)
- 标签
- 递交数
- 66
- 已通过
- 5
- 通过率
- 8%
- 被复制
- 7
- 上传者