P1466 集合 Subset Sums(01背包求填充方案数)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",dp[sum]/2); 26 } 27 } 28 return 0; 29 }
以上是关于P1466 集合 Subset Sums(01背包求填充方案数)的主要内容,如果未能解决你的问题,请参考以下文章
DP | Luogu P1466 集合 Subset Sums