编程语言
首页 > 编程语言> > 独立问题最优调度的算法合理性分析(详解)(附代码)

独立问题最优调度的算法合理性分析(详解)(附代码)

作者:互联网

思路:使用动态规划寻找到考虑所有问题后,机器A运行\(i\)分钟后,机器B运行的时间的最小值。之后再在所有的这\(i\)种情况中找到机器A和机器B共同运行的最小值。

子问题:

\(dp[i][j]\)表示在做前i个任务中,机器A运行\(j\)分钟的情况下B机器运行的最短时间

子问题之间的转移方程:

\[dp[i][j] = min(dp[i-1][j]+b[i],dp[i-1][j-a[i]]) \]

解释:

在考虑第\(i\)个任务时,机器B在机器A运行\(j\)分钟的情况下的最小值应该是

前\(i-1\)个任务机器B在A运行\(j\)分钟的情况下的最小值加上B机器运行第\(i\)个任务的时间

以及将这个任务交给A机器运行前\(i-1\)个任务中A机器运行\(j-a[i]\)分钟时,B机器运行时间的最小值。

最优子结构的证明:

当\(dp[i][j]\)取到最优时,如果前\(i-1\)个任务机器B在A运行\(j\)分钟的最短时间\(dp[i-1][j]\)还可以更短,或者如果前\(i-1\)个任务机器B在A运行\(j-a[i]\)分钟的最短时间还可以更短,那么\(dp[i][j]\)的值就可以更小,与假设矛盾。

为何本问题的解一定对应着机器B的时间要取最小值?

反证法:\(dp[n][j]\)是问题的解,对应着机器B运行时间的最小值。假设此时机器B的运行时间可以恰当增大,以此来使得总时间最小。那么,有下列三种情况:

算法复杂度分析:

一共有\(n\)种物品,所有物品的和为\(s\),因此子问题的规模大概是\(n*s\)个,解决一个子问题需要的复杂度为\(O(1)\),因此算法复杂度为\(O(sn)\),由于\(s\)可以特别大,所以这个算法不适用于\(s\)特别大的情况。

代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int dp[105][10024];
int a[105];
int b[105];
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
        cin >> b[i];
    int sum = 0;
    for (int i = 1; i <= n; i++)
    {
        sum += a[i]; //只考虑前i个,因此花时间最多不会超过前i个之和
        for (int j = 0; j <= sum; j++)
        {
            int cur_val = 0x3f3f3f3f;
            if (j - a[i] >= 0)
                cur_val = dp[i - 1][j - a[i]];
            dp[i][j] = dp[i - 1][j] + b[i];
            if (dp[i][j] > cur_val)
                dp[i][j] = cur_val;
        }
    }
    int ans = 0x3f3f3f3f;
    for (int i = 0; i <= sum; i++)
        if (ans > max(dp[n][i], i))
            ans = max(dp[n][i], i);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= sum; j++)
            cout<<dp[i][j]<<" ";
        cout<<endl;
    }
    cout << ans << endl;
    return 0;
}

标签:运行,机器,int,最小值,机器运行,算法,详解,合理性,dp
来源: https://www.cnblogs.com/xianyi-yk/p/14654850.html