• P1466 [USACO2.2]集合 Subset Sums


    P1466 [USACO2.2]集合 Subset Sums

    这也能动规,而且还是01背包.

     dp[i][j]表示从1~i的数字中选择,能够得到和为j的方案数.那么dp[i][0]=1.对于每个数字选或者不选,有:

    dp[i + 1][j] = dp[i][j] + dp[i][j - i],这里的i相当于背包问题中物体i的重量,这里的"重量"就是i自身.

    压维,dp[j] += dp[j - i].

    此时½∑i=1n即为选取和为两个子集的和的方案数.注意到这里面是有重复部分的,如{1,2,3}被拆分为方案①{1,2},{3}和方案②{3},{1,2}.

    输出该方案数除以二即可.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n, M;
    long long dp[800];
    
    int main(){
        cin >> n;
        M = n * n + n;
        if((M / 2) & 1){
            puts("0");
            return 0;
        }
        M /= 2;         // sum 1 to n
    
        dp[0] = 1;
        for(int i = 1; i <= n; i++)
            for(int j = M / 2; j >= i; j--)
                dp[j] += dp[j - i];
    
        cout << dp[M / 2] / 2;
    
        return 0;
    }
    还没完

     怎么看出来这是一道动规题?缩小范围,为什么这是一道背包问题?

    因为问题可以转化为取还是不取的问题,如果以搜索的视角看,还有存储结果的需求.

    如果说取还是不取,前一段时间做的搜索几乎一直在做这件事情,这两者之间的关系太紧密了.

  • 相关阅读:
    前端资源分享
    解决COM组件80070005错误
    【迁移】—Entity Framework实例详解 转
    IIS错误处理集合
    疯狂蚂蚁框架搭建
    MSSQL日期格式化
    一句SQL实现获取自增列操作
    mongodb 性能篇
    mongodb管理篇
    mongodb高级应用
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14087356.html
Copyright © 2020-2023  润新知