您的位置:首页 > 其它

动态规划-寻找最优分配时间。(未理解)

2016-01-07 20:17 344 查看
期末将至,是时候开始复习了。小c本学期共有N门课,编号从0到N-1。

此时离期末考还有M小时可以用来复习,小c决定不吃不睡不玩把这些时间全部用来复习这N门课。

对于第i门课,在目前(不复习)的情况下,他可以获得Si分。复习一次该门课程耗时Ti小时,同时会提高该门课Di分的总成绩(每门课的分数上限为100分)。此外,第i门课的学分记为Wi。

小c有2个目标:首先,他不希望挂掉任何一门课程,即不希望任何一门课程的总成绩低于60分;其次,他希望拿到尽可能高的总绩点。

单科绩点的计算方式为:G(p) = (p-50)/10.0

总绩点为所有科目绩点以该科目学分为权重的加权平均数。

现在小c告诉你N、M和这N门课的所有必要信息,请你帮他计算一下在不挂科的前提下他最高能拿到多少的总绩点。

输入格式:

输入包括N+1行:

第一行包括2个整数:N M;

随后N行,每行包括4个整数:Si Wi Ti Di

输出格式:

输出只包括一个浮点数,为小c在不挂科的前提下所能拿到的最高总绩点,保留到小数点后2位。

如果他很不幸无法避免必然的挂科命运,输出0(不是0.00)

不论怎样,你应该在输出数据之后再输出一个换行符。

数据规模:

1 ≤ N 10; 0 ≤ M ≤ 1000; 0 ≤ Si ≤ 100; 1 ≤ Wi ≤ 6; 1 ≤ Ti, Di ≤ 100

#include <stdio.h>

#define MAXn (10+1)
#define MAXt (1000+1)

#define MAX(x, y) (((x) > (y)) ? (x) : (y))

typedef struct {
int s, w, t, d;
} Course;

int main() {
int n, i, j, m;
Course c[MAXn];
scanf("%d%d", &n, &m);
for (i = 1; i <= n; ++i)
scanf("%d%d%d%d", &c[i].s, &c[i].w, &c[i].t, &c[i].d);

for (i = 1; i <= n && m >= 0; ++i)
if (c[i].s < 60) {
j = (59 - c[i].s + c[i].d) / c[i].d;
c[i].s += c[i].d * j;
if (c[i].s > 100)
c[i].s = 100;
m -= j * c[i].t;
}

if (m < 0) {
printf("0\n");
} else {
int w = 0;
for (i = 1; i <= n; ++i)
w += c[i].w;
double f[2][MAXt + 1] = { { 0 } };
for (i = 1; i <= n; ++i)
f[0][0] += c[i].w * (c[i].s-50);
f[1][0] = f[0][0];
for (j = 1; j <= m; ++j)
f[0][j] = f[0][0];

int k, tem;
for (i = 1; i <= n; ++i)
for (j = 1; j <= m; ++j) {
f[i % 2][j] = f[(i & 1) ^ 1][j];
tem = c[i].d;
for (k = c[i].t;
k<= j && tem + c[i].s < 100;
k += c[i].t, tem += c[i].d)
f[i & 1][j] = MAX(
f[i & 1][j],
f[(i & 1) ^ 1][j - k] + c[i].w * tem);
if (k <= j)
f[i & 1][j] = MAX(
f[i & 1][j],
f[(i & 1) ^ 1][j - k] + c[i].w * (100 - c[i].s));
}
printf("%.2lf\n", f[n & 1][m]/(w * 10.0));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: