UVA - 607 Scheduling Lectures(贪心+记忆化搜索)

来源:互联网 发布:股票收益率数据怎么找 编辑:程序博客网 时间:2024/05/18 03:55

题意:

有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个知识点的最小不满意度。

AC代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;int dp[1005][1005] ,t[1005];bool vis[1005][1005];int C, L, n;int DI(int time) {    if(time == 0) {        return 0;    }else if(1 <= time && time <= 10) {        return -C;    }else {        return (time - 10) * (time - 10);    }}int solve() {    int sum = 0 ,cnt = 1;    for(int i = 1; i <= n; i++) {        sum += t[i];        if(sum > L) {            sum = t[i];            cnt++;        }    }    return cnt;}int dps(int x,int y) {    if(x == 0) {        return y ? INF : 0;    }    if(vis[x][y]) {        return dp[x][y];    }    dp[x][y] = INF;    int sum = 0;    for(int i = y; i > 0; i--) {        sum += t[i];        if(sum > L)            break;        int ans = dps(x-1, i-1);        if(ans != INF) {            dp[x][y] = min(dp[x][y], ans + DI(L - sum));        }    }    vis[x][y] = true;    return dp[x][y];}int main() {    int cas = 1;    int flag = 0;    while(scanf("%d",&n) != EOF && n) {        if(flag++) {            printf("\n");        }        scanf("%d%d",&L,&C);        for(int i = 1; i <= n; i++) {            scanf("%d",&t[i]);        }        int cnt = solve();        memset(dp,0,sizeof(dp));        memset(vis,false,sizeof(vis));        printf("Case %d:\n",cas++);        printf("Minimum number of lectures: %d\n",cnt);        printf("Total dissatisfaction index: %d\n",dps(cnt, n));    }    return 0;}
0 0
原创粉丝点击