HDU 1476(Scheduling Lectures)

动态规划题,设 dp[i][j] 表示前 i 节课,讲 j 个主题,最小的不满指数。

状态转移方程为 dp[i][j] = min(dp[i][j], dp[i - 1][k] + DI(sum[j] - sum[k])),表示前 i-1 节课讲前 k 个主题,第 i 节课讲第 k+1 个至第 j 个主题。

#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;

int dp[MAXN][MAXN]; //dp[i][j]表示前i节课,讲j个主题,最小的不满指数
int time[MAXN]; //每个主题所需的时间
int sum[MAXN]; //sum[i]表示前i个主题所需的时间
int L, C; //一节课的时间,常数C

//计算不满指数
int DI(int t)
{
	t = L - t;
	if (t == 0)
		return 0;
	else if (t >= 1 && t <= 10)
		return -C;
	else
		return (t - 10) * (t - 10);
}

int main()
{
	int Case = 1; //测试用例数
	int n; //主题数
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)
			break;

		scanf("%d %d", &L, &C);
		sum[0] = 0;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &time[i]);
			sum[i] = sum[i - 1] + time[i];
		}
		for (int i = 0; i <= n; i++)
		{
			dp[i][0] = 0;
			for (int j = 1; j <= n; j++)
				dp[i][j] = INF;
		}

		for (int i = 1; dp[i - 1][n] == INF; i++) //课程数,i-1节课无法讲n个主题
		{
			for (int j = i; j <= n && sum[j] <= i * L; j++) //主题数
			{
				for (int k = j - 1; k >= i - 1; k--) //第i节课讲第k+1个至第j个主题
				{
					if (sum[j] - sum[k] <= L && dp[i - 1][k] != INF)
						dp[i][j] = min(dp[i][j], dp[i - 1][k] + DI(sum[j] - sum[k]));
					else if (sum[j] - sum[k] > L)
						break;
				}
			}
		}

		int index;
		for (index = 1; index <= n; index++)
		{
			if (dp[index][n] != INF)
				break;
		}
		if (Case > 1)
			printf("\n");
		printf("Case %d:\n\n", Case++);
		printf("Minimum number of lectures: %d\n", index);
		printf("Total dissatisfaction index: %d\n", dp[index][n]);
	}
	return 0;
}

继续加油。

发布了325 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Intelligence1028/article/details/105504660
hdu