有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;
}