目录
原题大意:
题目描述:
输入格式:
输出格式:
样例输入:
样例输出:
数据规模:
题目大意:
主要思路:
dp的转移:
dp初始化:
代码:
原题大意:
题目描述:
某台计算机有两个 CPU。现在有 n 个进程需要执行,而进程只有 k 种(编号为 1~k)。
第 i 种进程在任意一个 CPU 上执行时,如果该 CPU 上执行的前一个进程也是第 i 种,则只需要花费 时间;如果不是第 i 种,则需要花费时间。
现在你需要做进程调度,依次执行完 1~n 的进程。
需要注意,必须当第 i 个进程执行完之后,你才能安排第 i+1 个进程。请问执行完所有进程的最少时间是多少呢?
输入格式:
第一行包含一个整数 T,表示数据组数。
每组数据第一行包括两个数 n 和 k,接下来一行 n 个整数,表示每个进程是哪一种进程,接下来一行 k 个整数,表示 ~,再接下来一行 k 个整数。
输出格式:
输出 T 行,每行一个整数,表示答案。
样例输入:
9
3 2
1 2 2
3 2
2 1
4 2
1 2 1 2
5 3
2 1
4 3
1 2 3 1
100 100 100
1 1 1
5 2
2 1 2 1 1
65 45
54 7
5 3
1 3 2 1 2
2 2 2
1 1 1
5 1
1 1 1 1 1
1000000000
999999999
5 6
1 6 1 4 1
3 6 4 1 4 5
1 1 1 1 4 1
1 3
3
4 5 6
1 2 3
8 3
3 3 3 1 2 3 2 1
10 10 8
10 10 5
样例输出:
6
11
301
225
8
4999999996
11
6
63
数据规模:
,,。
题目大意:
给你多组数据,每组数据给你三个数组,让你安排进程,使得进程执行完的时间最小。
主要思路:
这一题用dp会好做,看上去很难,其实不难。dp[i][j] 代表对于前i个进程,选完第i个进程后,另一个CPU停留在j上,所用的最小时间。而且有个不起眼的小细节(一定会有一个CPU最后一个进程会停留在a[i-1]))
dp的转移:
这个难度也不大,首先是简单的:注意,这里用了三目运算符。
还有就是那个小细节:注意,这里也用了三目运算符。
dp初始化:
初始化成1e18,dp[0][0] 就应该是0。
代码:
#include<bits/stdc++.h>
using namespace std;
long long a[5010];
long long hot[5010],cold[5010];
long long dp[5010][5010];
//dp[i][j] 代表对于前i个进程,选完第i个进程后,另一个CPU停留在j上,而且一定会有一个CPU最后会停留在a[i-1]
int main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=k;i++)
{
cin>>cold[i];
}
for(int i=1;i<=k;i++)
{
cin>>hot[i];
}
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=k+1;j++)
{
dp[i][j] = 1e18;
}
}
dp[0][0] = 0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=k;j++)//k种进程
{
dp[i][j] = min(dp[i][j],dp[i-1][j]+(a[i-1] == a[i]?hot[a[i]]:cold[a[i]]));//选当前的
dp[i][a[i-1]] = min(dp[i][a[i-1]],dp[i-1][j]+(j == a[i]?hot[a[i]]:cold[a[i]]));//一定会有一个是a[i-1]的
}
}
long long ans=1e18;
for(int i=0;i<=k;i++)
{
ans = min(ans,dp[n][i]);
}
cout<<ans<<'\n';
}
return 0;
}