poj 1042 钓鱼问题 郭炜老师慕课例题(贪心+枚举)

题目链接:http://poj.org/problem?id=1042

这题是慕课郭炜老师算法课程里面的一道例题,我用他教的思路写出来的代码。 

 

代码长了点 但是内容简单  思路易懂!

 

附郭炜老师课件截图和视频讲解地址

 

1、题意:

 

2、分析 

 

 

 

本题思路就是枚举最终停下来的湖,这样就能算出纯钓鱼的时间片个数 K 。然后用一个三元组(F,i,j)表示第 i 个湖的第 j 个时间片所能钓到鱼的数量为F。然后按照钓鱼的数量从大到小排序(注意排序这块是个难点,要用到stable_sort 我就是在这错了)。取前K个即是问题的答案!

 

代码


#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#include<stdio.h>
#include<cstring>
#include<stdlib.h>
#include<sstream>
#include<set>
#include<cmath>
typedef long long ll;
using namespace std;

struct node1
{
    int fishnum;
    int time[30];
};
struct node2///(F,no,tt)三元组表示第no个湖的第tt个时间片所能钓到鱼的数量为F。
{
    int F;
    int no;
    int tt;
};
struct rule1
{
    bool operator()( const node1 &t1,const node1 &t2)
    {
        return t1.fishnum>t2.fishnum;
    }
};
struct rule2
{
    bool operator()(const node2 &t1,const node2 &t2)
    {
        return t1.F>t2.F;
    }
};
int maxfish;

int main()
{
//    freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n&&n)
    {
        node1 a[30];
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
                a[i].time[j]=0;
        }
        int h;
        maxfish=0;
        int f[30];
        int d[30];
        int t[30];
        cin>>h;
        for(int i=1;i<=n;i++) cin>>f[i];
        for(int i=1;i<=n;i++) cin>>d[i];
        t[0]=0;//到第一个湖的时间为0
        for(int i=1;i<n;i++) cin>>t[i];
        int k=0;///纯钓鱼的时间片个数
        for(int x=1;x<=n;x++)///枚举最终停下来的湖
        {
            int walktime=0;//走路用的时间片
            for(int j=1;j<x;j++)
                walktime+=t[j];
            k=h*12-walktime;//纯钓鱼的时间片个数
            node2 m[5000];///最多就是n*k个
            int kase=0;
            int number=0;
            for(int i=1;i<=x;i++)
                for(int j=1;j<=k;j++)
                {
                    number=f[i]-(j-1)*d[i];
                    if(number>0)
                    {
                        m[kase].F=number;
                        m[kase].no=i;
                        m[kase].tt=j;
                        kase++;
                    }
                    else
                    {
                        m[kase].F=0;
                        m[kase].no=i;
                        m[kase].tt=j;
                        kase++;
                    }
                }
            stable_sort(m,m+kase,rule2());///!!!!!!!!!用
//            for(int i=0;i<kase;i++)
//            {
//                cout<<m[i].F<<" "<<m[i].no<<" "<<m[i].tt<<endl;
//            }
            int num=0;
            for(int i=0;i<k;i++)
                num+=m[i].F;
            a[x].fishnum=num;
            for(int i=0;i<k;i++)
            {
                for(int j=1;j<=x;j++)
                {
                    if(m[i].no==j)
                    {
                        if(m[i].tt>a[x].time[j])
                            a[x].time[j]=m[i].tt;
                    }
                }
            }
//            cout<<"-----------------------"<<endl;
        }
        sort(a+1,a+1+n,rule1());
        for(int i=1;i<=n;i++)
        {
            if(i==n)
                cout<<a[1].time[i]*5<<endl;
            else
                cout<<a[1].time[i]*5<<", ";
        }
        cout<<"Number of fish expected: "<<a[1].fishnum<<endl<<endl;
    }
    return 0;
}

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,可以得知这是一道关于迷宫问题的题目,需要使用Java语言进行编写。具体来说,这道题目需要实现一个迷宫的搜索算法,找到从起点到终点的最短路径。可以使用广度优先搜索或者深度优先搜索算法来解决这个问题。 下面是一个使用广度优先搜索算法的Java代码示例: ```java import java.util.*; public class Main { static int[][] maze = new int[5][5]; // 迷宫地图 static int[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // 方向数组 static boolean[][] vis = new boolean[5][5]; // 标记数组 static int[][] pre = new int[5][5]; // 记录路径 public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { maze[i][j] = sc.nextInt(); } } bfs(0, 0); Stack<Integer> stack = new Stack<>(); int x = 4, y = 4; while (x != 0 || y != 0) { stack.push(x * 5 + y); int t = pre[x][y]; x = t / 5; y = t % 5; } stack.push(0); while (!stack.empty()) { System.out.print(stack.pop() + " "); } } static void bfs(int x, int y) { Queue<Integer> qx = new LinkedList<>(); Queue<Integer> qy = new LinkedList<>(); qx.offer(x); qy.offer(y); vis[x][y] = true; while (!qx.isEmpty()) { int tx = qx.poll(); int ty = qy.poll(); if (tx == 4 && ty == 4) { return; } for (int i = 0; i < 4; i++) { int nx = tx + dir[i][0]; int ny = ty + dir[i][1]; if (nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && maze[nx][ny] == 0 && !vis[nx][ny]) { vis[nx][ny] = true; pre[nx][ny] = tx * 5 + ty; qx.offer(nx); qy.offer(ny); } } } } } ``` 该代码使用了广度优先搜索算法,首先读入迷宫地图,然后从起点开始进行搜索,直到找到终点为止。在搜索的过程中,使用标记数组记录已经访问过的位置,使用路径数组记录路径。最后,使用栈来输出路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值