zoukankan      html  css  js  c++  java
  • POJ 1873 The Fortified Forest

    POJ_1873

        由于树木比较少,可以枚举砍树的决策,然后计算砍掉的树木的长度是否比剩下的树木的凸包的周长要长,每次计算之后按题意更新最优解即可。

        在枚举的时候还可以应用一个剪枝,就是如果当前砍树损失的价值比记录的最小价值要大的话,就可以直接枚举下一种情况了,而不必再去花时间计算凸包和凸包的周长了,这样可以节省很多时间。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #define MAXD 20
    #define zero 1e-8
    #define INF 0x3f3f3f3f
    struct point
    {
    int x, y;
    }p[MAXD], res[MAXD], q[MAXD];
    int st, N, X, P, num, minv, v[MAXD];
    double w[MAXD], ans;
    int cmp(const void *_p, const void *_q)
    {
    point *p = (point *)_p, *q = (point *)_q;
    if(p->y == q->y)
    return p->x - q->x;
    return p->y - q->y;
    }
    int dcmp(double x)
    {
    return fabs(x) < 0 ? 0 : (x < 0 ? -1 : 1);
    }
    double sqr(double x)
    {
    return x * x;
    }
    int det(int x1, int y1, int x2, int y2)
    {
    return x1 * y2 - x2 * y1;
    }
    void init()
    {
    int i, j, k;
    for(i = 0; i < N; i ++)
    scanf("%d%d%d%lf", &p[i].x, &p[i].y, &v[i], &w[i]);
    }
    int del(int top, int i)
    {
    if(det(res[top].x - res[top - 1].x, res[top].y - res[top - 1].y, q[i].x - res[top].x, q[i].y - res[top].y) <= 0)
    return 1;
    return 0;
    }
    int graham()
    {
    int i, j, k, top = 1, mint;
    qsort(q, X, sizeof(q[0]), cmp);
    res[0] = q[0], res[1] = q[1];
    for(i = 2; i < X; i ++)
    {
    while(top && del(top, i))
    -- top;
    res[++ top] = q[i];
    }
    mint = top;
    res[++ top] = q[X - 2];
    for(i = X - 3; i >= 0; i --)
    {
    while(top != mint && del(top, i))
    -- top;
    res[++ top] = q[i];
    }
    return top;
    }
    double calculate()
    {
    int i, j, k;
    double t;
    if(X == 1)
    t = 0;
    else if(X == 2)
    t = 2 * sqrt(sqr(q[0].x - q[1].x) + sqr(q[0].y - q[1].y));
    else
    {
    P = graham();
    t = 0;
    for(i = 0; i < P; i ++)
    t += sqrt(sqr(res[i].x - res[i + 1].x) + sqr(res[i].y - res[i + 1].y));
    }
    return t;
    }
    void solve()
    {
    int i, j, k, cnt, value;
    double t, s;
    minv = num = INF;
    for(k = 1; k < (1 << N); k ++)
    {
    s = cnt = value = X = 0;
    for(j = 0; j < N; j ++)
    {
    if((1 << j) & k)
    {
    ++ cnt;
    value += v[j];
    s += w[j];
    }
    else
    q[X ++] = p[j];
    }
    if(value > minv)
    continue;
    t = calculate();
    if(dcmp(s - t) < 0)
    continue;
    if(value < minv || (value == minv && cnt < num))
    {
    minv = value;
    num = cnt;
    st = k;
    ans = s - t;
    }
    }
    printf("Cut these trees:");
    for(i = 0; i < N; i ++)
    if((1 << i) & st)
    printf(" %d", i + 1);
    printf("\n");
    printf("Extra wood: %.2lf\n", ans);
    }
    int main()
    {
    int t = 0;
    for(;;)
    {
    scanf("%d", &N);
    if(!N)
    break;
    init();
    if(t ++)
    printf("\n");
    printf("Forest %d\n", t);
    solve();
    }
    return 0;
    }


  • 相关阅读:
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Python eval() 函数
    Python repr() 函数
  • 原文地址:https://www.cnblogs.com/staginner/p/2357674.html
Copyright © 2011-2022 走看看