USACO Section 2.2 Subset Sums
在这之前做过九度的题,题目只要求判断能否构成那样的划分,没有让求不同划分的个数,所以dfs就能过,这题dfs到36时超时,各种剪枝都无效。。
后来看的题解,原来是DP。。。
学习了
先贴DP代码,再贴DFS的超时代码
1 /* ID:linyvxi1
2 PROB:subset
3 LANG:C++
4 */
5 #include <stdio.h>
6 int main()
7 {
8 freopen("subset.in","r",stdin);
9 freopen("subset.out","w",stdout);
10 int N;
11 scanf("%d",&N);
12 if((N*(N+1)/2)%2!=0){
13 printf("0\n");
14 return 0;
15 }
16 int sum=N*(N+1)/4;
17 long long final[40][400];
18 final[1][1]=1;
19 final[1][0]=1;
20 int i,j;
21 for(i=2;i<=N;i++){
22 for(j=0;j<=sum;j++){
23 if(j>=i){
24 final[i][j]=final[i-1][j]+final[i-1][j-i];
25 }else{
26 final[i][j]=final[i-1][j];
27 }
28 }
29 }
30 printf("%ld\n",final[N][sum]/2);
31 }
下面是DFS的超时代码
1 /* ID:linyvxi1
2 PROB:subset
3 LANG:C++
4 */
5 #include <stdio.h>
6 int N;
7 int total_sum;
8 int total_solutions=0;
9 void dfs(int next_pos,int cur_sum)
10 {
11 if(next_pos>N){
12 return;
13 }
14 if(cur_sum*2>total_sum){
15 return;
16 }
17 if(cur_sum*2==total_sum){
18 total_solutions++;
19 return;
20 }
21
22 if((cur_sum+total_sum-(next_pos)*(next_pos-1)/2)*2<total_sum){
23 return;
24 }
25
26 dfs(next_pos+1,cur_sum+next_pos);
27 dfs(next_pos+1,cur_sum);
28 }
29 int main()
30 {
31 freopen("subset.in","r",stdin);
32 freopen("subset.out","w",stdout);
33 scanf("%d",&N);
34 total_sum=N*(N+1)/2;
35 if(total_sum%2!=0){
36 printf("0\n");
37 return 0;
38 }
39 if(!(N%4==0||(N+1)%4==0)){
40 printf("0\n");
41 return 0;
42 }
43 int cur_sum=0;
44 dfs(1,0);
45 printf("%d\n",total_solutions);
46 }