Section 4.1 Fence Rails(DFS_ID迭代加深搜索+剪枝)

本文介绍如何通过深度优先搜索(DFS)结合剪枝技巧解决FenceRails问题,涉及多维背包问题的优化。

Fence Rails
Burch, Kolstad, and Schrijvers

Farmer John is trying to erect a fence around part of his field. He has decided on the shape of the fence and has even already installed the posts, but he's having a problem with the rails. The local lumber store has dropped off boards of varying lengths; Farmer John must create as many of the rails he needs from the supplied boards.

Of course, Farmer John can cut the boards, so a 9 foot board can be cut into a 5 foot rail and a 4 foot rail (or three 3 foot rails, etc.). Farmer John has an `ideal saw', so ignore the `kerf' (distance lost during sawing); presume that perfect cuts can be made.

The lengths required for the rails might or might not include duplicates (e.g., a three foot rail and also another three foot rail might both be required). There is no need to manufacture more rails (or more of any kind of rail) than called for the list of required rails.

PROGRAM NAME: fence8

INPUT FORMAT

Line 1:N (1 <= N <= 50), the number of boards
Line 2..N+1:N lines, each containing a single integer that represents the length of one supplied board
Line N+2:R (1 <= R <= 1023), the number of rails
Line N+3..N+R+1:R lines, each containing a single integer (1 <= ri <= 128) that represents the length of a single required fence rail

SAMPLE INPUT (file fence8.in)

4
30
40
50
25
10
15
16
17
18
19
20
21
25
24
30

OUTPUT FORMAT

A single integer on a line that is the total number of fence rails that can be cut from the supplied boards. Of course, it might not be possible to cut all the possible rails from the given boards.

SAMPLE OUTPUT (file fence8.out)

7

题目:http://ace.delos.com/usacoprob2?a=98sI0RlsOtq&S=fence8

题意:给你n块木板,和 r 个需求,也就是用n块木板切割成小木板,使得更多的小木板满足需求。。。

分析:这题初看会发现是一道多维的背包问题,不过维度太高,背包是不可能了。这种情况下,往往只能暴力了,而暴力的最佳选择就是深搜+剪枝。。。

而这个DFS_ID嘛以前没听说过,不过貌似用过,就是限制每次搜索的深度而已,只用DFS_ID还是不行,这时候就要加上各种剪枝了,这里就不透露剪枝了,自己想出来最好

其实我是看到是DFS后乱搞过的,有个优化是错误的,不过是小概率的错误,所以AC了,只有一组用来0.011s,呵呵

代码:

/*
ID: 15114582
PROG: fence8
LANG: C++
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[55],b[1111],c[1111];
int n,r,sum;
int dfs(int t,int sum,int p)
{
    if(t<0)return 1;
    if(sum<c[t])return 0;
    int i=0,j;
    if(b[t]==b[t+1])i=p+1;
    for(j;i<n;++i)
        if(a[i]>=b[t])
        {
            a[i]-=b[t];
            j=dfs(t-1,sum-b[t]-(a[i]>=b[0]?0:a[i]),p);
            a[i]+=b[t];
            if(j>0)return 1;
            if(j<0)return 0;
            if(a[i]==b[t])return -1;
        }
    return -1;
}
int main()
{
    freopen("fence8.in","r",stdin);
    freopen("fence8.out","w",stdout);
    int i,l,ans,m;
    while(~scanf("%d",&n))
    {
        for(sum=i=0;i<n;++i)
            scanf("%d",&a[i]),sum+=a[i];
        scanf("%d",&r);
        for(i=0;i<r;++i)
            scanf("%d",&b[i]);
        sort(b,b+r);
        for(c[0]=b[0],i=1;i<r;++i)
            c[i]=c[i-1]+b[i];
        ans=l=0,--r;
        while(r&&sum<c[r])--r;
        while(l<=r)
        {
            m=(l+r)>>1;
            if(dfs(m,sum,-1)>0)ans=m+1,l=m+1;
            else r=m-1;
        }
        printf("%d\n",ans);
    }
    return 0;
}



这段代码实现了一个名为 `updateFence` 的函数,其作用是根据无人机任务中的地理围栏点(`fencePoint`)更新围栏结构体(`MissionFence`)中的多边形信息(`polygonInfo`),并统计围栏中多边形或圆形区域的数量(`num_polygons`)。该函数通常用于无人机任务系统中解析地理围栏指令。 --- ### 函数功能说明: - **输入参数**: - `missionFence_o`:指向 `MissionFence` 结构体的指针,表示当前任务的地理围栏信息。 - `num_polygons`:用于输出解析出的围栏区域(多边形或圆形)数量。 - **主要逻辑**: - 遍历 `fencePoint[]` 数组中的所有围栏项。 - 根据每项的命令类型(`nav_cmd`)判断是返回点、圆还是多边形顶点。 - 如果是圆或有效多边形顶点,则在 `polygonInfo[]` 中记录其类型、索引和相关信息。 - 最终统计出围栏区域的总数。 --- ### 代码解析: ```c void updateFence(MissionFence *missionFence_o, int32_t *num_polygons) { int num_fence_items = (*missionFence_o).fenceEntry.num_items; (*num_polygons) = 0; int current_seq = 1; while (current_seq <= num_fence_items) { bool is_circle_area = false; switch ((*missionFence_o).fencePoint[current_seq - 1].nav_cmd) { case MAV_CMD_NAV_FENCE_RETURN_POINT: // 返回点,不构成围栏区域,跳过 ++current_seq; break; case MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION: case MAV_CMD_NAV_FENCE_CIRCLE_EXCLUSION: // 圆形围栏(包含或排除) is_circle_area = true; // 注意:这里没有 break,会继续执行下面的 case,用于统一处理 case MAV_CMD_NAV_FENCE_POLYGON_VERTEX_INCLUSION: case MAV_CMD_NAV_FENCE_POLYGON_VERTEX_EXCLUSION: if (!is_circle_area && (*missionFence_o).fencePoint[current_seq - 1].vertex_count == 0) { // 非圆形且顶点数为0,跳过无效多边形 ++current_seq; } else { // 有效围栏区域,记录到 polygonInfo 中 (*missionFence_o).polygonInfo[(*num_polygons)].dataman_index = current_seq; (*missionFence_o).polygonInfo[(*num_polygons)].fence_type = (*missionFence_o).fencePoint[current_seq - 1].nav_cmd; if (is_circle_area) { // 圆形围栏,记录半径并跳过一个点 (*missionFence_o).polygonInfo[(*num_polygons)].circle_radius = (*missionFence_o).fencePoint[current_seq - 1].circle_radius; current_seq += 1; } else { // 多边形围栏,记录顶点数量并跳过所有顶点 (*missionFence_o).polygonInfo[(*num_polygons)].vertex_count = (*missionFence_o).fencePoint[current_seq - 1].vertex_count; current_seq += (*missionFence_o).fencePoint[current_seq - 1].vertex_count; } ++(*num_polygons); // 围栏数量加1 } break; default: // 其他不支持的围栏类型,跳过 ++current_seq; break; } } } ``` --- ### 数据结构说明: 1. **`MissionFence`**: ```c typedef struct { FenceEntry fenceEntry; // 围栏条目信息 FencePoint fencePoint[...]; // 围栏点数组 PolygonInfo polygonInfo[...]; // 多边形信息数组 } MissionFence; ``` 2. **`FencePoint`**: ```c typedef struct { uint16_t nav_cmd; // 围栏命令类型(MAV_CMD_NAV_FENCE_*) uint16_t vertex_count; // 多边形顶点数 float circle_radius; // 圆形围栏半径 float lat, lon; // 纬度和经度 } FencePoint; ``` 3. **`PolygonInfo`**: ```c typedef struct { int dataman_index; // 当前围栏区域在 fencePoint 中的起始索引 uint16_t fence_type; // 围栏类型(圆形/多边形,包含/排除) uint16_t vertex_count; // 顶点数(仅多边形使用) float circle_radius; // 半径(仅圆形使用) } PolygonInfo; ``` --- ### 示例说明: 假设 `fencePoint` 中有如下数据: | seq | nav_cmd | vertex_count | circle_radius | lat | lon | |-----|--------------------------|--------------|---------------|-----|-----| | 1 | MAV_CMD_NAV_FENCE_CIRCLE_INCLUSION | 0 | 50 | 47.1| 8.2 | | 2 | MAV_CMD_NAV_FENCE_POLYGON_VERTEX_INCLUSION | 3 | 0 | 47.2| 8.3 | | 3 | (same as 2) | | | 47.3| 8.4 | | 4 | (same as 2) | | | 47.4| 8.5 | 执行 `updateFence()` 后: - `polygonInfo[0]` 表示圆形围栏,半径 50,起始索引 1- `polygonInfo[1]` 表示三角形围栏,顶点数 3,起始索引 2。 - `*num_polygons = 2` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值