算法设计与分析第三章习题(1-10)参考代码

这篇博客涵盖了动态规划在解决一系列问题中的应用,包括独立任务最优调度、最优批处理、数字三角形、乘法表、租用游艇、汽车加油行驶、最小m段和问题、圈乘运算和最大长方体问题。每个问题都提供了详细的解题思路、递推公式以及参考代码实现。
摘要由CSDN通过智能技术生成

**3-1 独立任务最优调度问题

二维数组建立:
dp[i][j] 表示完成i个任务,机器A工作时间为j时,机器B工作的时间。
递推公式如下:
dp[i][j] = min(dp[i-1][j]+b[i],dp[i-1][j-a[i]])
示例:
输入:

6
2 5 7 10 5 2 
3 8 4 11 3 4

输出:
在这里插入图片描述

参考代码:

#include <iostream>
#include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <string>
#define inf 0x3f3f3f3f

using namespace std;

//独立任务最优调度问题
int main()
{
   
    int n;
    cin>>n;
    int a[101];
    int b[101];
    int sum = 0;
    int dp[101][10001];
    for(int i=1; i<=n; i++)
    {
   
        cin>>a[i];
    }
    for(int i=1; i<=n; i++)
    {
   
        cin>>b[i];
    }
    memset(dp,0,sizeof(dp));
    // 假设dp[i][j]为完成I个任务时机器工作的时间为J 时B机器工作的时间
    for(int i=1; i<=n; i++)
    {
   
        sum+=a[i];
        for(int j=0; j<=sum; j++)
          {
   
              dp[i][j] = dp[i-1][j]+b[i];
              if(j>=a[i])
              {
   
                  dp[i][j] =  min(dp[i-1][j]+b[i], dp[i-1][j-a[i]]);
              }
          }
    }
    int minn = inf;
    for(int i=0; i<=sum; i++)
    {
   
       int t = max(i,dp[n][i]);
       minn = min(minn,t);
    }
    cout<<minn<<endl;
    return 0;

}

**3-2 最优批处理问题:
解题思路:
dp[i]表示区间[i,n]上最小总费用
递推公式:
在区间 [i,n] 选一点 j
则dp[i] = min(dp[i],dp[j]+(s+t[i]+t[i+1]+…+t[j-1]) *(f[i]+f[i+1]+…+f[n]))
示例1:
输入:

5 
1
1 3
3 2
4 3
2 3
1 4

输出:

153

参考代码:

#include <iostream>
#include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <string>
#define inf 0x3f3f3f3f

using namespace std;
// 3-2 最优批处理问题

int main()
{
   
    int n,s;
    int t[101],f[101];
    //dp[i] = min(dp[i],dp[j]+(s+t[i]...t[j-1])*(f[i]+..+f[n]))
    int t_sum[101];
    int f_sum[101];
    int dp[101];
    memset(t_sum,0,sizeof(t_sum));
    memset(f_sum,0,sizeof(f_sum));
    memset(dp,inf,sizeof(dp));
    cin>>n>>s;
    for(int i=1; i<=n; i++)
    {
   
        cin>>t[i]>>f[i];
    }
    
    for(int i=n;i>=1;i--)
    {
   
        t_sum[i] = t_sum[i+1] + t[i];
        f_sum[i] = f_sum[i+1] + f[i];
    }
    dp[n+1] = 0;
    for(int i=n;i>=1;i--)
    {
   
        for(int j=i+1; j<=n+1; j++)
        {
   
            int sum_t = s + t_sum[i] - t_sum[j];
            int sum_f = f_sum[i];
            dp[i] = min(dp[i],dp[j]+sum_t*sum_f);
        }
    }
    cout<<dp[1]<<endl;
    return 0;

}

Sample
Input

4
4 4 5 9

Output

43
54

参考代码:

链接: (注释版代码)

#include <iostream>
#include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <string>
#define inf 0x3f3f3f3f

using namespace std;
// 3-3 石子合并问题
int main()
{
   
    int n;
    int a[202];
    int sum[202];
    
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值