POJ 3628 Bookshelf 2
题目的意思很清楚,就是说FJ(奶牛场主为我们提供了多少题目啊),有个书架(渣翻译),然后书架有个高度H,现在FJ有N个奶牛,每个奶牛有个高度hi,现在将奶牛堆起来(话说这怎么堆),使得堆起来的高度大于等于(注意等于,我第一次没有加等号,导致了一次wa)H,现在要求最小高度差。
本来是想用dp来做的,类似背包问题,后来看了下数据范围N<=20,而高度确很高,所以显然对于本题而言,直接dfs是不错的选择。
稍微加了一点小优化:
1.首先搜索顺序是从大到小搜,这样容易提前跳出。2.当当前高度+最小高度-H>=min(已知最小高度差)时就直接跳出
3.当min是0时直接跳出
代码如下:
#include <cstdio> #define MAXN 20 int N , H; int h[MAXN] , Min , S = 0; void init() { scanf("%d%d",&N,&H); for (int i = 0;i < N;i++) scanf("%d",&h[i]) , S += h[i]; for (int i = 0;i < N-1;i++) for (int j = i+1;j < N;j++) if (h[i] < h[j]) { int tmp = h[i]; h[i] = h[j]; h[j] = tmp; } Min = S-H; } void DFS(int depth , int sum) { if (!Min) return ; if (sum >= H) { if (sum - H < Min) Min = sum - H; return ; } if (depth == N) return ; if (sum + h[N-1] - H >= Min) return ; DFS(depth+1,sum+h[depth]); DFS(depth+1,sum); } int main () { init(); DFS(0,0); printf("%d\n",Min); return 0; }
测试结果如下: