UVa 607 Scheduling Lectures(简单DP)

题意:

有n个主题。每堂课的时间是L。每个主题各要求t1,t2,...tn(1<=ti<=L)。对于每个主题,你要决定要哪堂课教。并且有如下的规则:
1.每个主题必须完整地包含在一堂课里。不能分成两部分教。
2.主题之间的顺序不能调换,即主题i必须在主题i+1之前教。
同时,如果在每堂课的最后如果能留有10分钟以内的时候,那么学生的不满意程序是最小的。不满意程度的计算如下所示:
D=0(如果剩下的时间是0)。
D=-c(如果剩下的时间在10分钟以内)。
D=(t-10)^2(剩下的情况)

思路:

dp[i, j]表示前i节课,覆盖j个知识点的最小不满意度。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;

const int MAXN = 1010;
int dp[MAXN][MAXN];
int a[MAXN], sum[MAXN];
int L, C;

int getvalue(int v)
{
    int t = L - v;

    if (t == 0)
        return 0;
    else if (0 < t && t <= 10)
        return -C;
    else if (t > 10)
        return (t - 10) * (t - 10);
}

int main()
{
    int n;
    int cases = 0;
    while (scanf("%d", &n) && n)
    {
        scanf("%d %d", &L, &C);

        sum[0] = 0;
        for (int i = 1; i <= n; ++i)
            scanf("%d", &a[i]), sum[i] = sum[i-1] + a[i];

        for (int i = 0; i <= n; ++i)
        {
            dp[i][0] = 0;
            for (int j = 1; j <= n; ++j)
                dp[i][j] = INT_MAX;
        }

        for (int i = 1; dp[i-1][n] == INT_MAX; ++i)
            for (int j = i; j <= n && sum[j] <= i * L; ++j)
                for (int k = j; k >= i - 1; --k)
                    if (sum[j] - sum[k] <= L && dp[i-1][k] != INT_MAX) 
                        dp[i][j] = min(dp[i][j], dp[i-1][k] + getvalue(sum[j] - sum[k]));
                    else if (sum[j] - sum[k] > L)
                        break;
                        
        int i;
        for (i = 1; i <= n; ++i)
            if (dp[i][n] != INT_MAX)
                break;

        if (cases)
            printf("\n");
        printf("Case %d:\n", ++cases);
        printf("Minimum number of lectures: %d\n", i);
        printf("Total dissatisfaction index: %d\n", dp[i][n]);
    }
    return 0;
}

 

 

posted @ 2012-11-25 12:55  kedebug  阅读(711)  评论(0编辑  收藏  举报