题意
有M个任务,分给K个队完成。
任务分配需要连续,比如:
合法-------1队:0-5;2队:6-10
不合法----1队:0-5;2队:6-9;1队:10
每个任务有难度值D[i];每个队做完任务后,根据难度产生疲劳度T,疲劳度计算方式:
1、完成单个任务,T=0;
2、完成多个任务:
任务4到5,T=D[4]*D[5]
任务2到4,T=D[2] *(D[3]+D[4])+D[3] * D[4]
任务i到j:
T=
D[ i ] * (D[i+1] + D[i+2]…+D[j])+
D[i+1] * (D[i+2] …+ D[j])+
…
D[j-1] * D[j]
分配任务,求所有队伍疲劳度之和,最小值。
0<M<10000
0<K<200
0<D[i]<100
示例
输入:
2 1 -----2个任务,1个队伍
5 7 -----难度:任务0:5,任务1:7
输出:
35
输入:
4 2
1 2 6 1
输出:
8
#include<stdio.h>
#define MIN(a,b) (a)<(b)?(a):(b)
#define MAX(a,b) (a)>(b)?(a):(b)
unsigned int D[10000];//每个任务的难度
int M, K;//M个任务K个队伍
unsigned int D_sum_i_j[10000][10000];//i--j的任务,简简单单求和
unsigned int T_ij[10000][10000];//i--j的任务分配给一个队伍所产生的tired
unsigned int dp[10000][200];//下标0--i任务分给前j个队伍做,最小的tired总和
void input();
unsigned int add_overflow(unsigned int x, unsigned int y);
unsigned int mul_overflow(unsigned int a, unsigned int b);
/*
4 2
1 2 6 1
5 2
2 1 8 1 8
2 1
5 7
*/
int main()
{
int i, j, k;
input();
for (i = 0; i < M; i++)//遍历出所有i到j的D的和----D_sum_i_j,给T_ij用
{
D_sum_i_j[i][i] = D[i];
for (j = i+1; j < M; j++)
{
D_sum_i_j[i][j] = D_sum_i_j[i][j-1] + D[j];
}
}
for (i = 0; i < M; i++) //遍历出所有i到j的T,给dp用
{
T_ij[i][i] = 0;
for (j = i + 1; j < M; j++)
{
//T_ij[i][j] = T_ij[i][j - 1] + D_sum_i_j[i][j-1]* D[j];
T_ij[i][j] =
add_overflow(T_ij[i][j - 1],
mul_overflow(D_sum_i_j[i][j - 1], D[j])
);
}
}
for (j = 1; j <= K; j++)
{
for (i = j-1; i < M; i++)
{
if (i == j - 1)
dp[i][j] = 0;
else if (j==1)
{
dp[i][j] = T_ij[0][i];
}
else
{
dp[i][j] = UINT_MAX;
for (k = j - 2; k < i - 1; k++)
{
//0-i的任务,分给j个队伍,产生的最小T,由下面递推:
//0-k的任务,分给前j-1个队伍,最后一个队伍再分k+1到i。
//遍历所有可能的k,取最小的
//dp[i][j] = MIN(dp[i][j], dp[k][j - 1]+ T_ij[k+1][i]);
dp[i][j] =
MIN(dp[i][j],
add_overflow(dp[k][j - 1], T_ij[k + 1][i])
);
}
}
}
}
}
void input()
{
int i = 0;
scanf("%d %d", &M, &K);
for (i = 0; i < M; i++)
{
scanf("%d", &D[i]);
}
}
unsigned int add_overflow(unsigned int x, unsigned int y)
{
if (y > UINT_MAX - x)
return UINT_MAX;
return x + y;
}
unsigned int mul_overflow(unsigned int a, unsigned int b)
{
if (UINT_MAX / a < b) {
return UINT_MAX;
}
return a * b;
}