zoukankan      html  css  js  c++  java
  • 计数类DP——整数划分

    //背包:容量是n的背包,n个物品的体积分别是1,2,3……n,恰好装满背包的方案数,每个物品可以用无限次

    状态表示:f(i, j)

    集合:从1~i中选,体积恰好是j的方案

    属性:数量

    状态计算:

    f(i,j):i选了0,1,2,3……n个: f[i - 1][j], f[i-1][j-i], f(i-2, j - 2i), f(i-1,j-si)

    从1~i中选,选了2个i,并且和恰好为j

    从1~i-1中选,和为j - 2r

    ……

    f[i][j] = f[i-1][j] + f[i-1][j-i] + f[i-1][j-2i] + …… +f[i-1][j-i*s]

    f[i][j-i] =            f[i-1][j-i] + f[i-1][j-2i] +……+ f[i-1][j-i*s]

    ——> f[j] = f[j] + f[j-i]

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N = 1010, mod = 1e9 + 7;
    
    int n, f[N];
    
    int main()
    {
        cin>>n;
        f[0] = 1;
        
        for(int i = 1;i <= n; i++)
            for(int j = i; j <= n; j++)
            {
                f[j] = (f[j] + f[j - i]) % mod;
            }
        
        cout<<f[n]<<endl;
    }

    第二种解法:

      所有总和是i,并且可以恰好表示成j个数的和的方案

    f(i, j)

    方案中最小值是1 : 把最小值1去掉就是f[i-1][j-1]

    方案中最小值大于1: 把每个数都减去1:f[i-j, j]

    f[i][j] = f[i-1][j-1] + f[i-j,j]

    ans = f[n][1] + f[n][2]……f[n][n]

    完全背包的状态转移方程是:f[i][j] = f[i-1][j] + f[i][j-i]

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int N = 1010, mod = 1e9 + 7;
    
    int n, f[N][N];
    
    int main()
    {
        cin>>n;
        f[0][0] = 1;
        
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= i; j++)
            {
                f[i][j] = (f[i-1][j-1] + f[i-j][j]) % mod;
            }
        
        int ans = 0;
        for(int i = 1;i <= n;i++)
            ans = (ans + f[n][i]) % mod;
            
        cout<<ans<<endl;
    }
  • 相关阅读:
    Codeforces Round #136 (Div. 1) B. Little Elephant and Array
    洛谷 P2966 [USACO09DEC]牛收费路径Cow Toll Paths
    cogs 969. [NOIP2006] 数列
    防止xss(跨站脚本攻击)
    ☀【插件】iScroll
    ☀【移动优化】
    ☀【Zepto】
    ☀【JS】Code
    ☀【响应式设计】屏幕尺寸
    CODEVS——T2744 养鱼喂妹纸
  • 原文地址:https://www.cnblogs.com/longxue1991/p/12751450.html
Copyright © 2011-2022 走看看