什么原理?谁能帮我解释一下?

动规的数组关系式谁能解释一下?

#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 条评论

  • /*
    这个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
上传者