zoukankan      html  css  js  c++  java
  • USACO Subset Sums

    洛谷 P1466 集合 Subset Sums

    https://www.luogu.org/problemnew/show/P1466

    JDOJ 1681: Subset Sums

    https://neooj.com:8082/oldoj/problem.php?id=1681

    Description

    对于从1 到N 的连续整集合合,能划分成两个子集合,且保证每个集合的数字和是相等的.
    举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字和是相等的:
    {3} and {1,2}
    这是唯一一种分发(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)
    如果N=7,有四种方法能划分集合{1,2,3,4,5,6,7},每一种分发的子集合各数字和是相等的:
    {1,6,7} and {2,3,4,5} {注 1+6+7=2+3+4+5}
    {2,5,7} and {1,3,4,6}
    {3,4,7} and {1,2,5,6}
    {1,2,4,7} and {3,5,6}
    给出N,你的程序应该输出划分方案总数,如果不存在这样的划分方案,则输出0.程序不能预存结果
    直接输出.

    Input

    输入文件只有一行,且只有一个整数N

    Output

    输出划分方案总数,如果不存在则输出0.

    Sample Input

    Sample Output

    HINT

    N <= 39

    动归。

    最终可以转化成背包问题。为什么呢?

    因为题目中让你把集合中元素分成两个权值相等的部分,也就是说元素和相加除以2就是背包容量,我们的状态f[i][j]就设置为第i个元素装满容量为j的背包的方案数目。

    好了,现在这个题目就变成了01背包问题。

    只不过是求方案罢了。

    先上代码,再强调一下细节。

    AC CODE:

    #include<cstdio>
    using namespace std;
    int n,t,f[40][1000];
    int main()
    {
        scanf("%d",&n);
        t=(n+1)*n/2;
        if(t%2)
        {
            printf("0");
            return 0;
        }
        else 
            t/=2;
        f[1][1]=1;
        for(int i=2;i<=n;i++)
            for(int j=0;j<=t;j++)
            {
                if(j>i)
                    f[i][j]=f[i-1][j]+f[i-1][j-i];
                else
                    f[i][j]=f[i-1][j];
            }
        printf("%d",f[n][t]);
        return 0;
    }

    首先要判断当前集合的元素和能否被2整除,不能的话还玩个头。

    然后要设定初值,f[1][1]=1,我想不用多说。

    PS;有人也把f[1][0]设置为0了,我本人不是很理解,事实证明删去也毫无问题。

    然后开始DP,注意t要除以2。

    我们在每次状态转移之前要先加判断,如果可用空间比当前元素要大的话才可以把选和不选两种可能加到一起,否则就只能不选。

    选和不选的问题或者这段代码看不懂的请自行补习01背包。

    然后这道题就可以AC 了。

  • 相关阅读:
    【Swift后台】环境安装
    【Swift后台】背景介绍
    【Swift后台】目录
    退居三线iOS开发的自主开发历程
    Swift调用微信支付宝SDK(Swift4.0)
    ORACLE取对照表不等的数据
    Binary转换成Hex字符串
    利用OpenSSL创建证书链并应用于IIS7
    sysctl.conf和limit.conf备忘待查
    Use Wireshark to capture loopback traffic without a loopback adapter (转)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11203406.html
Copyright © 2011-2022 走看看