Luo Gu P1731 [NOI1999] && POJ 1190 birthday cake birthday cake

Topic Portal (Los Valley)   OR title Portal (POJ)

Problem-solving ideas:

A search problem, violence is easier to think out ideas, but do not prune This question will certainly TLE. So this question difficulty is how to prune.

1. If the current state of the answer is already seeking out answers bigger than our previous one state, then we have no need to search it, direct return.

2. If there is a state, after which assumes that all answers are best, but also the minimum value is greater than our current already seeking out, then wow oh you do not need to search down, return;

3. If, after a state, with all the layers of the cake are the largest volume, the volume can not reach the answer, then there is no need to search, return.

This question is for more than three pruning is enough.

If you still want to optimize it, you can find the current range of R and H each cake, enumerated in the range, this would also make the program a little faster, for this question, it is not necessary to write because // this pruning took me a half an hour, and finally not written right, directly remove this pruning, AC.

AC Code:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<math.h> 
 5 
 6 using namespace std;
 7 
 8 int n,m,ans = 0x7f7f7f7f,_min[25],oo[25];
 9 
10 int find_max(int nn,int h,int r) {
11     int vv = 0;
12     for(int i = 1;i <= m - nn + 1; i++) 
13         vv += (h - i) * (r - i) * (r - i);
14     return vv;
15 }
16 
17 inline void dfs(int deep,int h,int r,int v,int len) {
18     if(deep == m + 1) {
19         if(v != 0) return ;
20         ans = min(ans,len);
21         return ;
22     }
23     if(v < 0) return ;
24     int u = len;
25     u += _min[deep];
26     if(ans < u) return ;
27     u = find_max(deep,h,r);
28     if(v > u && deep != 1) return;
29     for(int i = 1;i < r; i++) {
30         for(int j = 1;j < h; j++) {
31             if(i * i * j > v) continue;
32             if(a[deep][i][j]) continue;
33             if(deep == 1) len = i * i;
34             dfs(deep + 1,j,i,v - j * i * i,len + 2 * j * i);
35         }
36     }
37 }
38 
39 inline void special() {
40     for(int i = 1;i <= sqrt(n); i++) {
41         if(n % (i * i) != 0) continue;
42         int j = n / (i * i);
43         int len = i * i + i * 2 * j;
44         ans = min(ans,len);
45     }
46 }
47 
48 int main()
49 {
50     scanf("%d%d",&n,&m);
51     for(int p = m;p >= 1; p--) 
52         _min[p] = _min[p+1] + (m - p + 1) * 2 * (m - p + 1);
53     if(m == 1) special();
54     else dfs(1,25,25,n,0);
55     if(ans == 0x7f7f7f7f) printf("0");
56     else printf("%d",ans);
57     return 0;
58 }

 

Guess you like

Origin www.cnblogs.com/lipeiyi520/p/11494862.html