zoukankan      html  css  js  c++  java
  • P1466 集合 Subset Sums(01背包求填充方案数)

    题目链接:https://www.luogu.org/problem/show?pid=1466

    题目大意:对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子集合的所有数字和是相等的:{3} 和 {1,2}.

    解题思路:01背包问题,设sum是1~n之和,其实就是求用数字1~n凑出sum/2的方案数(每个数字只能用一次),概括为以下几点:

         ①sum为奇数不能平分,直接输出0。

         ②求出来的方案数要除2,因为如果有一组能平分,那么凑出sum/2的方案数就是2。

         ③状态转移方程:dp[j]=dp[j]+dp[j-i]。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=1e4+5;
     6 
     7 long long dp[N];
     8 
     9 int main(){
    10     int n;
    11     while(~scanf("%d",&n)){
    12         memset(dp,0,sizeof(dp));
    13         int sum=(1+n)*n/2;
    14         if(sum%2==1)
    15             puts("0");
    16         else{
    17             sum/=2;
    18             dp[0]=1;
    19             for(int i=1;i<=n;i++){
    20                 for(int j=sum;j>=0;j--){
    21                     if(j>=i)
    22                         dp[j]+=dp[j-i];
    23                 }
    24             }
    25             printf("%lld
    ",dp[sum]/2);
    26         }
    27     } 
    28     return 0;
    29 }
  • 相关阅读:
    docker 清理日志文件
    POJ2182 Lost Cows
    POJ3468
    楼兰图腾
    P2024 [NOI2001]食物链
    POJ1733 Parity game
    洛谷P1196 [NOI2002]银河英雄传说
    洛谷P1955 [NOI2015]程序自动分析
    CF 660 C. Uncle Bogdan and Country Happiness
    CF 660A&B
  • 原文地址:https://www.cnblogs.com/fu3638/p/7777325.html
Copyright © 2011-2022 走看看