贪心问题(POJ1700/1017/1065)(C++)

信息学奥赛第十节 —— 贪心算法(渡河问题POJ 1700 Crossing River + 拦截导弹的系统数量求解) 复习概念 贪心算法又叫贪婪算法,是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,贪心算法不从整体最优上加以考虑,它所做出的是在某种意义上的局部最优解。 无后效性:贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。 贪心算法使用的前提:局部最优解一定能导致全局最优解。 贪心算法的过程 建立数学模型来描述问题 把求解的问题分成若干个子问题 对每一子问题求解,得到子问题的局部最优解 把子问题的局 阅读详情

一、贪心问题

贪心算法

贪心算法(greedy algorithm),是用计算机来模拟一个「贪心」的人做出决策的过程。这个人十分贪婪,每一步行动总是按某种指标选取最优的操作。而且他目光短浅,总是只看眼前,并不考虑以后可能造成的影响。

可想而知,并不是所有的时候贪心法都能获得最优解,所以一般使用贪心法的时候,都要确保自己能证明其正确性。

适用范围

贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。

证明

贪心算法有两种证明方法:反证法和归纳法。一般情况下,一道题只会用到其中的一种方法来证明。

1.反证法:如果交换方案中任意两个元素/相邻的两个元素后,答案不会变得更好,那么可以推定目前的解已经是最优解了。

2.归纳法:先算得出边界情况(例如 )的最优解 ,然后再证明:对于每个情况都可以由结论推导出结果。

常见题型

在OJ的问题中,最常见的贪心有两种。

1.「我们将 XXX 按照某某顺序排序,然后按某种顺序(例如从小到大)选择。」。

2.「我们每次都取 XXX 中最大/小的东西,并更新 XXX。」(有时「XXX 中最大/小的东西」可以优化,比如用优先队列维护)

二者的区别在于一种是离线的,先处理后选择;一种是在线的,边处理边选择。

排序解法

用排序法常见的情况是输入一个包含几个(一般一到两个)权值的数组,通过排序然后遍历模拟计算的方法求出最优值。

后悔解法

思路是无论当前的选项是否最优都接受,然后进行比较,如果选择之后不是最优了,则反悔,舍弃掉这个选项;否则,正式接受。如此往复。

贪心算法与动态规划的区别

贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。

二、POJ1700 Function Run Fun

2.1问题描述

问题截图

图2.1 问题截图

输入

输入的第一行包含一个整数T(1<=T<=20),即测试用例的数量。然后是T病例。每个案例的第一行包含N,第二行包含N个整数,给出每个人过河的时间。每个案例前面都有一个空行。不会超过1000人,没有人会超过100秒才能穿越。

输出

对于每个测试用例,打印一行,其中包含所有 N 人过河所需的总秒数。

2.2解题思路

题解

在解决这道过河问题时,我们可以使用贪心算法来最小化总时间。首先,将所有人的过河速度存储在一个数组中,并对其进行排序。接着,我们考虑以下三种情况:

1.如果还有4个或更多的人未过河,我们选择最快的人和最慢的人一起过河,然后最快的人返回;接着选择次快的人和第二慢的人一起过河,再让次快的人返回。重复此过程,直到只剩下3个人或更少。我们取这两种过河方式(最快带最慢和次快,或者最快和次快带最慢和次慢)中所需时间较短的一种。

2.如果剩下3个人未过河,我们让最快的人带最慢的人过河,然后最快的人返回,再带次慢的人过河,最后最快的人再过河。这样,三个人就能全部过河。

3.如果只剩下1个或2个人未过河,那么他们一定是过河速度最快的人(或其中两个),他们可以直接过河,无需再考虑时间。

算法设计路线

这里首先读取测试用例的数量,然后依次处理每个测试用例。对于每个测试用例,读取人数nPeople和每个人的过桥时间arrTimes。将过桥时间数组进行排序,使得过桥时间从小到大排列。这样可以方便后续的贪心策略应用。从后往前处理每个人的过桥时间,采用贪心策略选择最优的过桥方案:对于当前的最大时间的两个人(arrTimes[nIndex]和arrTimes[nIndex-1]),比较两种策略:最快的两个人带最慢的一个人过桥,最快的人返回,然后再带一个最慢的人过桥,最快的人再次返回。最快的一个人带次慢的人过桥,次慢的人返回,然后再带两个人过桥,最快的人返回。比较这两种策略的时间,选择其中较小的方案并累计到总时间nTotalTime。最后,处理剩余的情况(即人数少于等于3的情况):如果剩余3个人,直接累加这3个人的过桥时间。如果剩余2个人,累加这2个人的过桥时间。如果只剩1个人,累加这个人的过桥时间。输出当前测试用例的最短过桥总时间。通过上述步骤,算法在每个测试用例中选择最优的过桥方案,确保总时间最短。

2.3 C++源代码

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int nTestCases, nPeople, arrTimes[1001], nIndex, nTotalTime;

    // 读取测试用例的数量
    cin >> nTestCases;
    while (nTestCases--)
    {
        // 读取每个测试用例中的人数
        cin >> nPeople;
        nTotalTime = 0;

        // 读取每个人的过桥时间
        for (nIndex = 0; nIndex < nPeople; nIndex++)
            cin >> arrTimes[nIndex];

        // 对过桥时间进行排序
        sort(arrTimes, arrTimes + nPeople);

        // 计算总时间
        for (nIndex = nPeople - 1; nIndex > 2; nIndex -= 2)
            // 比较两种过桥方案的时间并选择最优方案
            if (arrTimes[0] + 2 * arrTimes[1] + arrTimes[nIndex] > 2 * arrTimes[0] + arrTimes[nIndex - 1] + arrTimes[nIndex])
                nTotalTime += 2 * arrTimes[0] + arrTimes[nIndex - 1] + arrTimes[nIndex];
            else
                nTotalTime += arrTimes[0] + 2 * arrTimes[1] + arrTimes[nIndex];

        // 处理剩余的情况
        if (nIndex == 2)
            nTotalTime += arrTimes[0] + arrTimes[1] + arrTimes[2];
        else if (nIndex == 1)
            nTotalTime += arrTimes[1];
        else
            nTotalTime += arrTimes[0];

        // 输出结果
        cout << nTotalTime << endl;
    }
    return 0;
}

正确结题截图

图2.2 正确解题截图

2.4复杂度分析

时间复杂度

1.读取输入:读取测试用例的数量和每个测试用例中的人数及其过桥时间需要O(n)的时间,其中n是测试用例中的人数。

2.排序:对每个测试用例中的过桥时间进行排序,使用了快速排序算法sort(arrTimes,arrTimes+nPeople),其平均时间复杂度为O(nlogn)。

3.计算总时间:在循环中处理每个过桥策略时,最多会进行n/2次迭代(因为每次迭代处理两个人)。每次迭代中的操作都是O(1)时间复杂度。因此,这部分的时间复杂度为O(n)。

4.处理剩余的情况:这部分处理的操作也是O(1)时间复杂度。

5.输出结果:输出结果需要O(1)时间复杂度。

综上所述,对于每个测试用例,主要的时间复杂度由排序过程决定,因此总的时间复杂度为O(nlogn)。假设有m个测试用例,则总的时间复杂度为O(m*nlogn)。

空间复杂度

1.空间使用:需要一个数组arrTimes来存储每个测试用例中的过桥时间,数组的大小为1001。其它变量如nTestCases、nPeople、nIndex和nTotalTime都是常数级的空间。

2.空间复杂度:因此,总的空间复杂度为O(1),因为无论测试用例数量和人数多少,空间需求都是固定的(数组大小固定为1001,且所有变量都是常数级别)。

综上所述,空间复杂度为O(1)。

三、POJ1017 Packets

3.1问题描述

问题截图

图3.1 问题截图

输入

输入文件由指定订单的几行组成。每行指定一个订单。顺序由六个整数描述,用一个空格分隔,依次表示从最小尺寸 1*1 到最大尺寸 6*6 的单个大小的数据包数。输入文件的末尾由包含六个零的行表示。

输出

输出文件包含输入文件中每行的一行。此行包含可以将输入文件相应行的订单打包到的最小包裹数量。输出文件中没有与输入文件的最后一行“null”对应的行。

3.2解题思路

题解

针对这道问题,我们可以优化逻辑来确保在装箱过程中最大化地利用空间,并且按照箱子规格从大到小的顺序进行贪心装箱。首先将所有箱子按照规格从大到小进行排序,例如先处理6x6、5x5、4x4的箱子,然后是3x3、2x2和1x1的箱子。对于6x6的箱子,因为只能装一个且全占满,所以直接用一个新箱子装一个6x6的箱子。对于5x5的箱子,同样用一个新箱子装一个5x5的箱子,然后检查是否可以装入1x1的箱子。对于4x4的箱子,同样先用新箱子装一个4x4的箱子,然后尽可能多地装入1x1或2x2的箱子。对于每个3x3的箱子,考虑放入已有箱子中的剩余空间或者使用新箱子。如果使用新箱子,则根据剩余空间可以装入的2x2箱子数量(0, 1, 3, 5)来确定是装4个、3个、2个还是1个3x3的箱子。如果将3x3的箱子放入已有箱子,则检查剩余空间并尽可能多地装入1x1或2x2的箱子。优先将2x2和1x1的箱子放入前面步骤中留下的剩余空间中。如果剩余空间不足以装下一个完整的2x2或1x1箱子,则使用新箱子来装它们。在装入箱子时,要始终保持记录哪些箱子有剩余空间以及剩余空间的大小。当有多个箱子可选时(例如,一个已有箱子剩余空间可以装一个2x2或两个1x1),优先选择能装入更大规格箱子的箱子,以最大化空间利用。计算出所有箱子被装入后所需的总箱子数。最终输出总箱子数作为结果。

通过上述步骤,我们可以确保在装箱过程中最大化地利用了空间,并且按照箱子规格从大到小的顺序进行了贪心装箱,这样可以有效地减少所需的总箱子数。

算法设计路线

这个算法的目的是计算所需的最少箱子数量,以便能够装下所有规格的箱子。每种规格的箱子都有固定的体积和占用空间。算法通过贪心策略逐步计算出所需的最少箱子数量。具体步骤如下:读取各规格箱子的数量:1x1, 2x2, 3x3, 4x4, 5x5, 6x6。如果所有箱子的数量都是0,则结束输入循环。将所有6x6, 5x5, 4x4箱子单独装箱。计算装3x3箱子的最少箱子数量,每4个3x3箱子需要一个箱子,若有剩余则需额外的箱子。每个4x4箱子可以额外装5个2x2箱子。计算未装满的3x3箱子对2x2箱子的影响(每个3x3箱子可影响剩余的2x2箱子空间)。计算是否需要额外的箱子来装2x2箱子,若需要则增加箱子的数量。计算总箱子数剩余的1x1箱子空间,若需要则增加箱子的数量。输出当前测试用例的最少箱子数量。

3.3 C++源代码

#include <iostream>
using namespace std;

int main() {
    int nBoxes1x1, nBoxes2x2, nBoxes3x3, nBoxes4x4, nBoxes5x5, nBoxes6x6; // 各种规格箱子的数量
    int nRemainingSpace1x1, nRemainingSpace2x2; // 分别为规格1和规格2的箱子剩余的空间
    int nTotalBoxes; // 所需的箱子总数量

    while (true) {
        // 读取输入
        cin >> nBoxes1x1 >> nBoxes2x2 >> nBoxes3x3 >> nBoxes4x4 >> nBoxes5x5 >> nBoxes6x6;

        // 当所有箱子的数量都为0时,退出循环
        if (nBoxes1x1 + nBoxes2x2 + nBoxes3x3 + nBoxes4x4 + nBoxes5x5 + nBoxes6x6 == 0) {
            break;
        }

        // 计算所需的箱子总数量
        nTotalBoxes = nBoxes6x6 + nBoxes4x4 + nBoxes5x5 + (nBoxes3x3 + 3) / 4;

        // 计算规格为2的箱子剩余空间
        nRemainingSpace2x2 = nBoxes4x4 * 5; // 规格4的箱子每个还能装5个规格2的箱子

        // 判断规格为3的箱子数量
        if (nBoxes3x3 % 4 == 3) {
            nRemainingSpace2x2 += 1;
        }
        else if (nBoxes3x3 % 4 == 2) {
            nRemainingSpace2x2 += 3;
        }
        else if (nBoxes3x3 % 4 == 1) {
            nRemainingSpace2x2 += 5;
        }

        // 如果规格1和规格2的箱子仍没有装完
        if (nRemainingSpace2x2 < nBoxes2x2) {
            nTotalBoxes += ((nBoxes2x2 - nRemainingSpace2x2) + 8) / 9;
        }

        // 计算规格1的箱子剩余空间
        nRemainingSpace1x1 = 36 * nTotalBoxes - 36 * nBoxes6x6 - 25 * nBoxes5x5 - 16 * nBoxes4x4 - 9 * nBoxes3x3 - 4 * nBoxes2x2;
        if (nRemainingSpace1x1 < nBoxes1x1) {
            nTotalBoxes += ((nBoxes1x1 - nRemainingSpace1x1) + 35) / 36;
        }

        // 输出所需的箱子总数量
        cout << nTotalBoxes << endl;
    }

    return 0;
}

正确解题截图

图3.2 正确解题截图

3.4复杂度分析

时间复杂度

1.读取输入和初始化:O(1)。

2.初步计算箱子数量:O(1)。

3.计算规格2的剩余空间:O(1)。

4.计算需要额外的2x2箱子数量:O(1)。

5.计算规格1的剩余空间:O(1)。

6.输出结果: O(1)。

综上所述,每个测试用例的时间复杂度是O(1)。对于 m 个测试用例,总的时间复杂度是O(m)。

空间复杂度

算法只使用了几个常数级别的变量来存储输入和中间结果,如 nBoxes1x1, nBoxes2x2, nBoxes3x3, nRemainingSpace1x1, nRemainingSpace2x2 等。算法不依赖于输入大小来分配额外的空间。综上所述,空间复杂度是 O(1)。

四、POJ1065 Wooden Sticks

4.1问题描述

问题描述

图4.1 问题截图

输入

输入由 T 个测试用例组成。测试用例数 (T) 在输入文件的第一行中给出。每个测试用例由两行组成:第一行有一个整数 n , 1 <= n <= 5000 ,表示测试用例中木棍的数量,第二行包含 2n 个正整数 l1 , w1 , l2 , w2 ,..., ln , wn ,每个数量级最多 10000,其中 li 和 wi 是第 i 根木棍的长度和重量, 分别。2n 个整数由一个或多个空格分隔。

输出

输出应包含最短设置时间(以分钟为单位),每行一个。

4.2解题思路

题解

针对这道问题,一个简单的思路就是根据长度排序,然后找出每一个节点前面的重量小于它的节点,最为一个子序列,在找子序列时,为了不影响到后面节点的子序列,需要找出自己能够接受的重量最大的工件放在前面,同时标记已经选过的节点,这里用到了一点点的贪心算法,最后用DP数组记录每一个工件在子序列中的顺序。最后只需要统计出每一个子序列中顺序为1的个数,就可以找到子序列的个数,子序列的个数就是本题目的答案。

算法设计路线

这里首先读取每个测试用例中的矩形数量。初始化动态规划数组和标志数组。读取每个矩形的长和宽。对矩形数组按照长和宽进行排序。使用双重循环计算每个矩形的最长递增子序列长度。内部循环用于查找前一个矩形能否接在当前矩形后面,形成递增子序列,并更新最长递增子序列的长度。统计最长递增子序列的数量。

4.3 C++源代码

#include <iostream>
#include <algorithm>

using namespace std;

// 定义节点结构体,表示每个矩形的长和宽
struct SNode
{
    int nLength; // 矩形的长度
    int nWidth;  // 矩形的宽度
    SNode(int nL = 0, int nW = 0) : nLength(nL), nWidth(nW) {}
};

int anDp[5007]; // 动态规划数组,用于存储最长递增子序列的长度
int nNodesCount; // 矩形的数量
bool abFlag[5007]; // 标志数组,标记哪些矩形已被处理
SNode aNodes[5007]; // 矩形数组

// 比较函数,用于排序节点
bool CompareNodes(const SNode& rNodeA, const SNode& rNodeB)
{
    if (rNodeA.nLength != rNodeB.nLength)
    {
        return rNodeA.nLength < rNodeB.nLength;
    }
    else
    {
        return rNodeA.nWidth < rNodeB.nWidth;
    }
}

// 初始化数组
void Initialize()
{
    for (int nIndex = 0; nIndex <= nNodesCount; nIndex++)
    {
        anDp[nIndex] = 1; // 初始化每个位置的最长递增子序列长度为1
        abFlag[nIndex] = true; // 初始化每个位置的标志为true
    }
}

// 输入函数
void Input()
{
    for (int nIndex = 1; nIndex <= nNodesCount; nIndex++)
    {
        scanf("%d%d", &aNodes[nIndex].nLength, &aNodes[nIndex].nWidth); // 输入每个矩形的长和宽
    }
    sort(aNodes + 1, aNodes + nNodesCount + 1, CompareNodes); // 按照长和宽进行排序
}

// 动态规划函数
void PerformDp()
{
    int nMaxIdx = -1; // 存储当前最长递增子序列的前一个位置
    int nMaxVal = -1; // 存储当前最长递增子序列的前一个位置的宽度值
    for (int nCurrentIdx = 1; nCurrentIdx <= nNodesCount; nCurrentIdx++)
    {
        anDp[nCurrentIdx] = 1; // 初始化当前矩形的最长递增子序列长度为1
        nMaxIdx = -1; // 初始化最大索引为-1
        nMaxVal = -1; // 初始化最大值为-1
        for (int nPrevIdx = nCurrentIdx - 1; nPrevIdx >= 1; nPrevIdx--)
        {
            // 判断当前矩形能否接在前一个矩形后面形成递增子序列
            if (abFlag[nPrevIdx] && aNodes[nCurrentIdx].nWidth >= aNodes[nPrevIdx].nWidth)
            {
                // 如果当前前一个矩形的宽度大于最大值或在相同宽度下前一个索引较大,则更新最大值和最大索引
                if (nMaxVal < aNodes[nPrevIdx].nWidth || (nMaxVal == aNodes[nPrevIdx].nWidth && nMaxIdx < nPrevIdx))
                {
                    nMaxVal = aNodes[nPrevIdx].nWidth;
                    nMaxIdx = nPrevIdx;
                }
            }
        }
        // 如果找到有效的前一个矩形,则更新当前矩形的最长递增子序列长度,并标记前一个矩形为已处理
        if (nMaxIdx >= 1)
        {
            anDp[nCurrentIdx] = anDp[nMaxIdx] + 1;
            abFlag[nMaxIdx] = false;
        }
    }
}

// 找到结果,即找到最长递增子序列的长度
int FindResult()
{
    int nResult = 0; // 初始化结果为0
    for (int nIndex = 1; nIndex <= nNodesCount; nIndex++)
    {
        if (anDp[nIndex] == 1) // 统计长度为1的子序列个数
        {
            nResult++;
        }
    }
    return nResult; // 返回结果
}

int main()
{
    int nTestCases; // 测试用例数量
    scanf("%d", &nTestCases);
    while (nTestCases--)
    {
        scanf("%d", &nNodesCount); // 输入每个测试用例中的矩形数量
        Initialize(); // 初始化数组
        Input(); // 输入矩形数据并排序
        PerformDp(); // 执行动态规划计算
        printf("%d\n", FindResult()); // 输出结果
    }
    return 0;
}

正确结题截图

图4.2 正确解题截图

4.4复杂度分析

时间复杂度

1.输入和初始化: O(n)

2.排序: O(n log n)

3.动态规划计算: O(n^2)

4.统计结果: O(n)

综上所述,对于每个测试用例,总的时间复杂度为 O(n^2)。

空间复杂度

算法使用了几个大小为 n 的数组:

1.anDp 数组:存储每个位置的最长递增子序列长度。

2.abFlag 数组:标记哪些矩形已被处理。

3.aNodes 数组:存储矩形的长和宽。

综上所述,总的空间复杂度为 O(n)。

五、实习小结

经过本次贪心算法的上机实习,我深刻体验了贪心算法的核心思想和实际应用。在实习过程中,我不仅巩固了理论知识,还通过编程实践加深了对贪心算法的理解。

我系统回顾了贪心算法的基本原理,即每一步都选择当前状态下的最优解,期望通过这些局部最优解最终导出全局最优解。通过深入学习,我了解到贪心算法的关键在于“贪心”的选择标准,这需要对问题的本质有深刻的理解。

在编程实践中,我解决了多个经典的贪心算法问题,如活动选择问题、背包问题的贪心近似解等。这些实践让我更加熟悉了贪心算法的实现过程,并锻炼了我的编程能力。在解决这些问题的过程中,我体会到了贪心算法的优势和局限性,并学会了如何根据问题的特点选择合适的贪心策略。

同时,我也意识到了贪心算法在实际应用中的挑战。有些问题虽然可以使用贪心算法解决,但得到的解可能不是全局最优解。因此,在选择使用贪心算法时,我们需要对问题的性质进行仔细分析,确保贪心策略的有效性。

此外,在实习过程中,我还注重了代码的优化和性能分析。我尝试使用不同的数据结构来存储中间结果,以减少时间复杂度和空间复杂度。同时,我也对算法的执行效率进行了测试和分析,以找出可能的性能瓶颈。

总的来说,本次贪心算法的上机实习让我收获颇丰。我不仅掌握了贪心算法的基本原理和实现方法,还学会了如何将其应用于实际问题中。同时,我也认识到了贪心算法的局限性和挑战,这将对我未来的学习和工作产生积极的影响。在未来,我将继续深入学习算法知识,提高自己的编程能力和问题解决能力。

贪心问题 贪心算法经典例题 一、什么是贪心算法 贪心算法是从先从局部最优出发进而达到全局最优效果的算法,要求我们找出如何使局部达到最优效果的规律,然后应用这个规律去算出全局最优效果。贪心算法就是只看眼前的小利但是经过累计后取得大利的算法。 二、贪心算法思路 在读题的过程中,体会到题目使用到的是一种贪心策略。有了这道题目是贪心问题的直觉,就需要考虑算法了。通过样例,找找思路与规律,找出题目中的贪心规律,把贪心规律应用起来,写代码找到最优解。 找贪心规律这一步是最难的,你要通过题目中的样例是如何求解的找到思路,明确题目是 阅读详情

相关推荐

【Crossing River】

渡过问题,贪心算法,动态规划

优快云 2880

基础贪心问题总结

贪心,就是取局部最优解,通常贪心问题能获得最优解的情况都是当前局部最优不会影响到全局最优,或者可以扩大到全局最优,如果从全局的角度来看,当前局部最优的选择策略是错误的,那么贪心算法就不适用了 贪心问题就是不考虑全局,尽可能的选择某种属性的物品,只有当局部最优可以扩展到全局最优的时候,贪心的策略才是正确的 主要有以下几种类型 1.简单贪心 简单贪心顾名思义就是我们可以很容易的做出某种选择,通常是考虑题目中的特性 ...

qq12323qweeqwe的博客 1602

手机Camera硬件电路设计:从电源管理到信号完整性的实战解析

本文深入解析了手机Camera硬件电路设计的核心挑战与实战经验,重点聚焦于电源管理与信号完整性两大基石。文章详细阐述了AVDD、DVDD、IOVDD和AFVDD四路电源的差异化设计要点与噪声控制策略,并剖析了MIPI等高速信号通道的完整性设计原则,为硬件工程师提供了从理论到PCB布局布线的完整实战指南。

weixin_28308325的博客 248

贪心问题求解思路(总结)

贪心问题: 局部最优解, 需证明该解就是该题的最优解无其他情况,则能直接用贪心法。典型例题: 部分背包问题, 直接用贪心法求的解即最优解,;而0-1背包问题额不能用贪心法去求最优解。 下面给出几道贪心的典型例题,在知道思路的情况,可遇到题目则以不变应万变去求解。 例题1 : 区间选点 给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数N,表示区间数。 接下来N行,每行包含两.

刘小雨的博客 1335

每天一个优秀提示词学习收藏 - 文本创作篇(二)

宝子们,今天不藏私啦!我把这段时间四处搜罗、潜心钻研出来的文本创作 Prompt 提示词大礼包双手奉上,这可都是能让你的 AI 创作水平原地起飞的干货!走过路过不要错过,赶紧码住,开启你的 AI 创作进阶之旅吧!

2399

谷歌DreamFusion使用方法及实例详解

DreamFusion 是谷歌提出的基于文本生成3D模型的突破性技术,无需3D训练数据,通过2D扩散模型(如Imagen)与NeRF(神经辐射场)结合实现。以下为使用社区开源实现(如。)的详细步骤及实例。

主攻大数据 人工智能 物联网 安全 低空经济等方向。mtsc 、gtest特邀分享嘉宾 1042

贪心算法(一)

1、poj1700过河问题 先排序,然后假设数据为t1 t2 t3 t4 t5 t6 t7 t8,只会有两种方式: 方式一:最快的两个作为划回的船,两个来回运走两个最慢的,好处是最慢的和次慢的组合消除掉次慢的时间,坏处是往回划的有一半是次快的。时间:t1+2*t2+t8 方式二:只有最快的作为划回的船,两个来回运走两个最慢的,好处是往回划的时间是最优的,坏处是往对岸划的次慢的时间也走了。时间...

cjavacjavacjava的博客 262

Qt Tab Widget 实战:如何打造一个可动态增删的标签页管理器(附完整代码)

本文深入探讨了使用Qt框架中的Tab Widget控件构建动态标签页管理器的实战方法。通过分析动态增删的核心挑战,提供了完整的C++代码示例,涵盖信号槽机制、页面生命周期管理、上下文菜单实现以及状态持久化等关键功能,帮助开发者打造高效、用户友好的桌面应用界面。

bb456的博客 1042

POJ--1700:Crossing River (贪心)

1. 题目源地址:http://poj.org/problem?id=1700 2. 解题思路:

酒酿小圆子呀~ 735

Unity3D用c#脚本调用前端javascript函数:H5获取unity - webgl 加载并初始化完成的消息

unity3d发布的Webgl 可以作为静态文件加载到H5页面中,并通过javascript 调用unity内置的C#脚本函数,详见Webgl调用unity api。而往往我们需要知道Webgl ready的消息,本文将给出unity 内部调用javascript函数的方案加以解决。

Bravo 2475

C++高级数据结构算法 | 二叉树的四种遍历算法详解(递归与非递归实现)

二叉树遍历方法 、前序遍历算法 、中序遍历算法 、后序遍历算法 、层序遍历算法

ZY-JIMMY 2562

贪心算法的五个经典问题分析和实现

问题1:活动安排问题 问题描述: 现在给你一个会场,有许社团需要在这个会场上活动, 已知各个社团在这个会场上活动的时间(起始时间和终止时间) 要求出来怎么安排 能够使得这个教室z在这一天之内接待尽可能多的社团  解题思路与算法思想 已经知道我们有n个活动需要安排 不妨考虑我们需要首先安排哪个活动 如果这n个活动的开始时间分别为a1-an 结束时...

weixin_42222917的博客 8714

VMware16虚拟机:下载和安装教程

VMware16 虚拟机 下载和安装教程

MQ0522的博客 20万+

常见贪心问题详解

常见贪心策略详解

m0_72674633的博客 1276

LDO参数解读、特性、参考设计

目录 一、工作原理 二、基本参数解释 三、LDO的一些特性 1、输出自放电 2、软启动 3、LDO效率 4、动态负载调整(∆VOUT) 5、线性瞬态响应 6、压差(Dropout Voltage) 四、参考设计 1、输入输出电容选择 2、Layout参考 一、工作原理 LDO是Low Dropout Regulator的缩写,意思是低压差线性稳压器,下面是LDO的内部框图,大致的工作原理就是:参考电压Vref和反馈电压FB(VOUT通过两个电阻分压)分别接在误差放大器的反向和正向

记得诚 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

POJ 1700 经典过河问题(贪心)

POJ题目链接:http://poj.org/problem?id=1700 N个人过河,船每次最多只能坐两个人,船载每个人过河的所需时间不同,问最快的过河时间。 思路: 当时所需要的最小时间很容易求得,现在由,假设n个人单独过河所需要的时间存储在数组 中,将数组 按升序排序,那么 这时将单独过河所需要时间最多的两个旅行者送到对岸去。 有两种方式: 1> 最快的(即所用...

不二的博客 998

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

POJ - 1700 crossing river(贪心算法)

crossing river 几个人过河,每次过两人一人回,速度由慢者决定,问过河所需最短时间。 【输入】 输入t组数据,每组数据第1行输入n,第2行输入n个数,表示每个人过河的时间。 【输出】 输出t行数据,每行1个数,表示每组过河最少时间。 【输入样例】 1 4 1 2 5 10 【输出样例】 17 思路:我最开始认为是最快的和最慢的一起过河,最快的回来,可是并不得17, 后来发现其实是 1和2过河,1回来 用时2+1 4和5过河,2回来 用时5+2 最后1和2过河,用时1+2,总用时17 所以我们计算

00后的博客 1232

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

贪心问题详解

贪心算法思想: 顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

一笑何方的博客 619

poj 1700 (贪心 or DP)

dp的思路和贪心思路是一样的, 只不过是用dp模拟了贪心的过程,我的贪心的代码不够简洁。 思路: 首先先让1和 2 走过去。 每次选择两种方式的一种 1:让 1 载着最慢的人走过去,然后再让 1 回来 2:先让 1 过去,让最慢的载着次慢的回来,再让2 过去接 1 。 第一种是回来的时间达到了最短,但是把人接到对岸时间有点长。 第二种是去对岸的时间达到最短(指单次操作)。 #include &lt...

幽灵悠悠 193

算法模板:经典贪心问题

讲解经典的贪心问题,带你在这些经典的贪心问题当中领略贪心思想的奥妙。

只想和你一起进步 1034

poj1700快速渡河问题(贪心策略,详细解析)

二、快速渡河问题 翻译为中文 一队人(N个人)期望跨河,有一条船,一次只能载2个人,过河之后需要有一个人划回来,所有人才能够跨河,每个人划船速度都不同,两个人一组整体速度是由划船速度较慢的决定的。问题:确定一种策略用最少的时间所有人都能过河。 输入: 方案数:T(1<=T<=20) 人数:N<1000 速度:<100s 输出: 最少的时间 样例: 输入: 1 4 1 2 ...

gl620321的博客 2069

POJ 1700 解题报告——Crossing River:求过河的最少时间问题

题目是说有N个人用一条船过河,船每次最多只能载2人,所以得多次来回穿梭才能将所有人运过河。为了减少所花时间,一般两人一起坐船过河,然后其中较快的一人划回来。 当N = 1,2 时,直接过河; 当N = 3 时,最快的人分两趟将另两人运过河; 当N >= 4 时:因一次可以载两人过河,故可以两人过河看作一个基本单位。每次用最短时间把最慢的两人运过河后,直至剩余人数小于4。设当前N人中最快与次快

江湖中人的专栏 2146

poj 1700 Crossing River

原题: http://poj.org/problem?id=1700 //经典过河问题 //题目大意: 有N个人要过河,但是只有一艘船,每次最多只能坐两个人,而过河后,如果还有人需要渡河,就需要岸上某个人重新把船划回来 // 每个人单独划船的速度已知,两个人一起坐船的速度取决于速度较慢的那个人,问这n个人渡河需要的最少时间 //思路:如果有4个人渡河a,b,c,d,速度由小

zark721的博客 437

POJ 1700(过河问题)

玩过《雷顿》就知道这题可以贪心 小等于2人:1,2-&gt; 3人时: 1,3-&gt; 1&lt;- 1,2-&gt; 1&lt;- 否则: 1,2-&gt; 2&lt;- max1,max2-&gt; 1&lt;- OR: 1,max1-&gt; 1&lt;- 2,max2-&gt; 2&lt;- 于是数据规模-2 Program P1700; v...

爱.NET 148

详解贪心算法的几个经典问题

详解贪心算法的几个经典问题 ...

weixin_44602007的博客 2778

poj1700 poj2573 经典贪心

4 1 2 5 10 答案:17  顺序是:1、2去,1回;5、10去;2回;1、2去。 1) 如果N=1、2,所有人直接过桥。   2) 如果N=3,由最快的人往返一次把其他两人送过河。   3) 如果N≥4,设A、B为走得最快和次快的旅行者,过桥所需时间分别为a、b;而Z、Y为走得最慢和次慢的旅行者,过桥所需时间分别为z、y。那么    当2b>a+y时,使用模式一将Z和Y

转角的守望 746
上一篇: 专题地图制作(安徽省区域5A级别景区分布图)全流程教学
下一篇: 动态规划问题(POJ1579/1458/1088)(C++)
CUGLin
博客等级 码龄4年 585粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值