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;
}

  测试结果如下:

你可能感兴趣的:(poj)