题目链接:https://www.luogu.com.cn/problem/P1466
题目的意思就是将1~n中的数分成两组,两组的和都为1~n的和的一半即n*(n+1)/2/2,不限制每组中数字的个数。
我们将题目意思转化一下,我们取k(0<k<n)个数让他们的和为n*(n+1)/2/2,我们求一下满足的方案数即可,注意一下就是要将数组开到long,可能会溢出(我用int试了一下,有一个测试点会WA)
这样就是很明显的01背包了,这道题稍微转化一下思想即可
这道题目就是赤裸裸的01背包,求方案数的模板题目:小A点菜
#include<bits/stdc++.h>
using namespace std;
long dp[805];
int main(){
int n;
scanf("%d",&n);
//如果1~n的和为奇数则没办法分成两半
if((n*(n+1)>>1)&1){
printf("0\n");
return 0;
}
dp[0]=1;
for(int i=1;i<=n;i++){
for(int j=n*(n+1)>>1;j>=i;j--){
dp[j]+=dp[j-i];
}
}
printf("%ld\n",dp[n*(n+1)>>2]>>1);
return 0;
}