**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];