有n个主题。每堂课的时间是L。每个主题各要求t1,t2,...tn(1<=ti<=L)
现在每堂课有m分钟 求最小需要几堂课 可以讲完这些主题 然后是满意度尽量低 满意度怎么算题目有图
因为一定要按照顺序讲每个主题 然后就可以贪心求出最小需要的课堂数
dp[i][j] 代表 i堂课 讲j个主题最小的满意度
然后推吧
dp[i][j] = min(dp[i][j], dp[i-1][k]+ok(m-(sum[j]-sum[k])));
枚举i j, k
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 1010; int a[maxn]; int sum[maxn]; int dp[maxn][maxn]; int c; int ok(int x) { if(!x) return x; if(x <= 10) return -c; return (x-10)*(x-10); } int main() { int cas = 0; int n, m; while(scanf("%d", &n) && n) { if(cas++) puts(""); scanf("%d %d", &m, &c); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); sum[i] = a[i] + sum[i-1]; } memset(dp, 0x7f, sizeof(dp)); for(int i = 0; i < n; i++) dp[i][0] = 0; int cnt = 0; int s = 0; for(int i = 1; i <= n; i++) { if(s + a[i] <= m) s += a[i]; else { cnt++; s = a[i]; } } cnt++; //printf("%d\n", cnt); for(int i = 1; i <= cnt; i++) { for(int j = i; j <= n; j++) { if(sum[j] > i*m) break; for(int k = j-1; k >= 0; k--) { if(sum[j] - sum[k] > m) break; dp[i][j] = min(dp[i][j], dp[i-1][k]+ok(m-(sum[j]-sum[k]))); } } } printf("Case %d:\nMinimum number of lectures: %d\nTotal dissatisfaction index: %d\n", cas, cnt, dp[cnt][n]); } return 0; }
UVa 607 Scheduling Lectures / 分不出什么类型的DP!!!,布布扣,bubuko.com
UVa 607 Scheduling Lectures / 分不出什么类型的DP!!!
原文:http://blog.csdn.net/u011686226/article/details/21086991