那些年,我们一起做过的贪心

本文介绍了一个简单的算法问题,关于如何通过将一组具有特定长度和宽度的方木按升序排列来最小化处理这些方木所需的准备时间。文章提供了一种有效的解决方案,并附带了完整的C++实现代码。
题目意思非常简单,有一堆方木需要处理,处理准备时间如下:第一块方木需要时间为1;如果当前处理方木的长宽都大于等于前一块方木,那么准备时间为0。
 
此题wrong answer了一次,主要是先前的思路是错误的。先前的想法是,按照l进行排序,然后再统计w的逆序个数;同时按照w排序,再统计l逆序的个数。最后,取其中的最小值。后来,发现这种思路是严重有问题的!
 

其实这个题十分简单,就是将所有的数据分成几个集合,每一个集合都是升序的,然后统计集合最小的个数。

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
  
typedef struct{
   int l,w,vi;
}point;
  
point p[5005];
  
bool cmp1(const point &p1,const point &p2)
{
   if(p1.l==p2.l) return p1.w<p2.w;
   return p1.l<p2.l;
}
  
void solve()
{
    int n,i,j,te,sum=0;
    scanf("%d",&n);
    for(i=0;i<n;i++){
       scanf("%d %d",&p[i].l,&p[i].w);
       p[i].vi=0;
    }
  
    sort(p,p+n,cmp1);
    for(i=0;i<n;i++)
    {
        if(p[i].vi==0)
        {
            sum++;p[i].vi=1;
            te=i;
            for(j=te+1;j<n;j++)
               if(p[j].vi==0 && p[te].w<=p[j].w) { te=j; p[j].vi=1; }
        }
    }
    printf("%d\n",sum);
}
  
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)  solve();
    return 0;
}


### 贪心算法与栈结合解决旅行商问题的方法和实现 贪心算法是一种通过逐步选择局部最优解来构建全局最优解的策略。在旅行商问题(TSP)中,贪心法可以通过最近邻点策略或最短链接策略来实现。然而,栈作为一种数据结构,通常用于处理具有后进先出(LIFO)特性的场景。结合栈和贪心算法解决旅行商问题,可以利用栈记录路径的选择过程,并在需要回溯时提供便利[^1]。 #### 方法描述 1. **初始化**:从起始点开始,将该点压入栈中。 2. **选择下一个城市**:根据贪心策略(例如最近邻点策略),从未访问的城市集合中选择距离当前城市最近的一个城市,并将其压入栈中。 3. **标记已访问城市**:将当前城市标记为已访问状态。 4. **检查是否完成遍历**:如果所有城市均已访问,则从栈中弹出最后一个城市并返回起始点,完成路径闭合。 5. **回溯机制**:如果某个城市没有未访问的邻居城市,则从栈中弹出该城市,回到前一个城市继续寻找新的路径。 #### 实现代码 以下是一个基于贪心算法和栈的旅行商问题解决方案的伪代码示例: ```python def tsp_greedy_with_stack(graph, start): stack = [start] # 使用栈存储路径 visited = set([start]) # 记录已访问的城市 path = [] # 最终路径 while stack: current_city = stack[-1] unvisited_neighbors = [ city for city in graph[current_city] if city not in visited ] if unvisited_neighbors: # 如果存在未访问的邻居城市 next_city = min(unvisited_neighbors, key=lambda x: graph[current_city][x]) # 贪心选择最近的邻居 stack.append(next_city) # 将下一个城市压入栈 visited.add(next_city) # 标记为已访问 else: # 如果没有未访问的邻居城市 if len(visited) == len(graph): # 如果所有城市均已访问 path = stack + [start] # 完成路径闭合 break else: # 否则回溯 stack.pop() # 弹出当前城市 return path, sum(graph[path[i]][path[i + 1]] for i in range(len(path) - 1)) # 返回路径和总距离 # 示例图的邻接表表示 graph = { 0: {1: 2, 2: 4, 3: 6, 4: 8}, 1: {0: 2, 2: 3, 3: 5, 4: 7}, 2: {0: 4, 1: 3, 3: 4, 4: 6}, 3: {0: 6, 1: 5, 2: 4, 4: 2}, 4: {0: 8, 1: 7, 2: 6, 3: 2} } path, total_distance = tsp_greedy_with_stack(graph, 0) print("Path:", path) print("Total Distance:", total_distance) ``` 上述代码实现了基于贪心算法和栈的旅行商问题求解方法。其中,`graph` 是一个邻接表表示的图,`start` 是起始城市。通过栈记录路径选择的过程,并利用贪心策略选择最近的邻居城市[^2]。 #### 结果分析 通过上述方法,可以得到一条满足旅行商问题约束的路径。对于给定的图,假设起始点为 0 点,最终路径可能为 `0-1-2-3-4-0` 或 `0-2-1-3-4-0`,且路径长度之和为 16[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值