码迷,mamicode.com
首页 > 其他好文 > 详细

P1466 集合 Subset Sums(01背包求填充方案数)

时间:2017-11-03 12:59:12      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:==   get   nbsp   col   name   else   子集   string   code   

题目链接: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\n",dp[sum]/2);
26         }
27     } 
28     return 0;
29 }

 

P1466 集合 Subset Sums(01背包求填充方案数)

标签:==   get   nbsp   col   name   else   子集   string   code   

原文地址:http://www.cnblogs.com/fu3638/p/7777325.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!