POJ1190 解题报告

  1 #include <cstdlib>
2 #include <iostream>
3 #include <cmath>
4 #include <vector>
5 #include <algorithm>
6 using namespace std;
7 int N,M;
8 int currentMinArea = INT_MAX;
9
10 static int exeCount = 0;
11 struct Column{
12 public:
13 int Ri;
14 int Hi;
15 public:
16 Column(int i=0,int j=0)
17 {
18 Ri = i;
19 Hi = j;
20 }
21
22 int getColumnArea() const
23 {
24 return 2*Ri*Hi;
25 }
26 int getColumnVolumn() const
27 {
28 return Ri*Ri*Hi;
29 }
30 float getSVRatio() const
31 {
32 return 2/Ri;
33 }
34 };
35 //c1面积是否大于C2
36 bool greaterAreaThan(const Column& c1,const Column& c2)
37 {
38 if(c1.getColumnArea() > c2.getColumnArea())
39 return true;
40 else return false;
41 }
42 //面积与体积比较大的优先;
43 bool greaterSVRatioThan(const Column& c1,const Column& c2)
44 {
45 if(c1.getSVRatio() > c2.getSVRatio())
46 return true;
47 else return false;
48 }
49 int getMinimunArea(int layer)
50 {
51 int area = 0;
52 for(int i=1;i<=layer;i++)
53 area += 2*i*i;
54 return area;
55 }
56 int getMinimunVolumn(int layer)
57 {
58 int volumn = 0;
59 for(int i=1;i<= layer;i++)
60 volumn += i*i*i;
61 return volumn;
62 }
63 int getMaximunVolumn(int RI,int HI,int layer)
64 {
65 int maxArea = 0;
66 for(int i=layer-1;i>=0;i--)
67 {
68 maxArea += (RI-i)*(RI-i)*(HI-i);
69 }
70 return maxArea;
71 }
72 int getLayerCakeArea(int RI,int HI,int volumn,int layer,int area)
73 {
74 int min = INT_MAX;
75 bool foundAnswer = false;
76 //vector<Column> oneLayerVector;
77 if(layer == 0 && volumn == 0)
78 return 0;
79 else if(layer == 0)
80 return -1;
81 if(volumn <= 0)
82 return -1;
83 if(area + getMinimunArea(layer) > currentMinArea) //pruning;
84 return -1;
85 if(area + volumn/RI*2 > currentMinArea)
86 return -1;/*
87 if(getMaximunVolumn(RI,HI,layer) < volumn) //剪枝;
88 return -1;*/
89 if(volumn < getMinimunVolumn(layer)) //pruning;
90 return -1;
91 if(RI < 0 || HI < 0 || volumn < 0)
92 {
93 cerr << "error in logic design" << endl;
94 return -1;
95 }
96 int temp = -1;
97 int i=0;
98 if(RI < sqrt((float)volumn/layer))
99 i = RI;
100 else i = (int)sqrt((float)volumn/layer);
101 for(;i>=layer;i--)
102 for(int j=layer;j<= HI && j<= volumn/(i*i) ;j++)
103 {
104 //pruning
105 /*if(area + 2*i*j + getMinimunArea(layer-1) >= currentMinArea) //pruning;
106 continue;
107 if(volumn-i*i*j < getMinimunVolumn(layer-1)) //pruning;
108 continue;
109 if(volumn-i*i*j > getMaximunVolumn(i-1,j-1,layer-1))
110 continue;
111 */
112 if(area + volumn/i*2 > currentMinArea)
113 continue;
114 /*exeCount ++;
115 if(exeCount%200000 == 0)
116 cout << "EXE Counter" << exeCount << endl;
117 */
118 temp = getLayerCakeArea(i-1,j-1,volumn-i*i*j,
119 layer-1,2*i*j+area);
120 if(temp >= 0)
121 {
122 foundAnswer = true;
123 temp += 2*i*j;
124 if(temp < min)
125 min = temp;
126 }
127 /*if(volumn-i*i*j >0)
128 {
129 oneLayerVector.push_back(Column(i,j));
130 }*/
131 }/*
132 sort(oneLayerVector.begin(),oneLayerVector.end(),greaterSVRatioThan);
133 vector<Column>::iterator iter = oneLayerVector.begin();
134 while(iter != oneLayerVector.end())
135 {
136 temp = getLayerCakeArea(iter->Ri-1,iter->Hi-1,volumn-iter->getColumnVolumn(),
137 layer-1,iter->getColumnArea()+area);
138 if(temp >= 0 )
139 {
140 foundAnswer = true;
141 temp = temp+iter->getColumnArea();
142 return temp;
143
144 if(temp < min)
145 min = temp;
146 if(temp >= currentMinArea)
147 return -1;
148 }
149 iter++;
150 }*/
151 if(foundAnswer == true)
152 return min;
153 else return -1;
154 }
155
156
157 int getCakeArea()
158 {
159 int temp = -1;
160 int volumn = N;
161 int layer = M;
162 int min = INT_MAX;
163 bool foundAnswer = false;
164 int i=0;
165
166 //vector<Column> firstLayerArea;
167 for(int i=(int)sqrt((float)volumn/layer);i>=layer;i--)
168 for(int j=layer;j<= volumn/(i*i);j++)
169 {
170 /*if(2*i*j+i*i + getMinimunArea(layer-1) >= currentMinArea) //pruning;
171 continue;
172 if(volumn-i*i*j < getMinimunVolumn(layer-1)) //pruning;
173 continue;
174 if(volumn-i*i*j > getMaximunVolumn(i-1,j-1,layer-1))
175 continue;*/
176 if(volumn-i*i*j >=0)
177 {
178 temp = getLayerCakeArea(i-1,j-1,volumn-i*i*j,layer-1,2*i*j+i*i);
179 if(temp >= 0 )
180 {
181 foundAnswer = true;
182 temp = temp+2*i*j + i*i;
183 if(temp < min)
184 {
185 min = temp;
186 currentMinArea = min;
187 }
188 }
189 }
190 }/*
191 sort(firstLayerArea.begin(),firstLayerArea.end(),greaterAreaThan);
192 vector<Column>::reverse_iterator iter = firstLayerArea.rbegin();
193 while(iter!=firstLayerArea.rend())
194 {
195 temp = getLayerCakeArea(iter->Ri -1,iter->Hi -1,
196 volumn-iter->getColumnVolumn(),layer-1,iter->getColumnArea()+iter->Ri*iter->Ri);
197 if(temp >= 0 )
198 {
199 foundAnswer = true;
200 temp = temp+iter->getColumnArea() + iter->Ri*iter->Ri;
201 //cout << temp << endl;
202 //return temp;
203 if(temp < min && temp >=0)
204 {
205 min = temp;
206 currentMinArea = min;
207 }
208 }
209 iter ++;
210 }*/
211 if(foundAnswer)
212 return min;
213 else return 0;
214 }
215 int main(int argc, char *argv[])
216 {
217 //time_t start,end;
218 //start = clock();
219 if(cin >> N >> M)
220 {
221 currentMinArea = INT_MAX;
222 cout << getCakeArea() << endl;
223 }
224 //end = clock();
225 //cout << (start-end)/CLOCKS_PER_SEC << endl;
226 //system("PAUSE");
227 return EXIT_SUCCESS;
228 }
229 /*4 6 2 1*/

主要的剪枝:  

  if(area + volumn/i*2 > currentMinArea) continue;

这个剪枝是最主要的,其他的剪枝的作用也不是很明显,但是如果去掉这个一定会超时;

posted @ 2011-07-25 14:35  天堂一梦  阅读(313)  评论(0编辑  收藏  举报