標籤:
題目傳送門
題意:教授給學生上課,有n個主題,每個主題有ti時間,上課有兩個限制:1. 每個主題只能在一節課內講完,不能分開在多節課;2. 必須按主題順序講,不能打亂。一節課L時間,如果提前下課了,按照時間多少,學生會有不滿意度。問最少要幾節課講完主題,如果多種方案輸出不滿意度最小的
分析:dp[i]表示前i個主題最少要多少節課講完,那麼這個主題可能和上個主題在同一節課講或者多開新的一節課講,狀態轉移方程:看代碼;優先滿足節數少的情況
收穫:普通的遞推DP
代碼:
/************************************************* Author :Running_Time* Created Time :2015-8-29 15:48:09* File Name :UVA_607.cpp ************************************************/#include <cstdio>#include <algorithm>#include <iostream>#include <sstream>#include <cstring>#include <cmath>#include <string>#include <vector>#include <queue>#include <deque>#include <stack>#include <list>#include <map>#include <set>#include <bitset>#include <cstdlib>#include <ctime>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1typedef long long ll;const int N = 1e3 + 10;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;int dp[N], d[N], a[N];int n, L, C;int get_DI(int x) { if (!x) return 0; if (1 <= x && x <= 10) return -C; else return (x - 10) * (x - 10);}int main(void) { int cas = 0; while (scanf ("%d", &n) == 1) { if (!n) break; scanf ("%d%d", &L, &C); for (int i=1; i<=n; ++i) scanf ("%d", &a[i]); dp[0] = d[0] = a[0] = 0; for (int i=1; i<=n; ++i) { dp[i] = dp[i-1] + 1; d[i] = d[i-1] + get_DI (L - a[i]); int cur = 0; for (int j=i; j>=1; --j) { cur += a[j]; if (cur > L) break; if (dp[j-1] + 1 < dp[i] || (dp[j-1] + 1 == dp[i] && d[j-1] + get_DI (L - cur) < d[i])) { dp[i] = dp[j-1] + 1; d[i] = d[j-1] + get_DI (L - cur); } } } if (cas) puts (""); printf ("Case %d:\n", ++cas); printf ("Minimum number of lectures: %d\n", dp[n]); printf ("Total dissatisfaction index: %d\n", d[n]); } return 0;}
遞推DP UVA 607 Scheduling Lectures