http://acm.hdu.edu.cn/showproblem.php?pid=4968
给定平均分和科目数量,要求保证及格的前提下,求平均绩点的最大值和最小值。
dp[i][j]表示i个科目,总分j的情况,离线预处理以后直接输出即可
dp[i + 1][j + k] = max/min(dp[i][j] + gpa[k]);
//去掉60分以下的无用段可以提速.
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include<map>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define clr0(x) memset(x,0,sizeof(x))
double f[12][1200];
double g[12][1200];
double gpa[120]; int main() {
for (int i = 60; i <= 69; i++)
gpa[i] = 2.0;
for (int i = 70; i <= 74; i++)
gpa[i] = 2.5;
for (int i = 75; i <= 79; i++)
gpa[i] = 3;
for (int i = 80; i <= 84; i++)
gpa[i] = 3.5;
for (int i = 85; i <= 100; i++)
gpa[i] = 4.0; for (int i = 0; i <= 10; i++)
for (int j = 0; j <= 1000; j++) {
f[i][j] = -1e9;
g[i][j] = 1e9;
}
f[0][0] = g[0][0] = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j <= 1000; j++) {
for (int k = 60; k <= 100; k++) {
f[i + 1][j + k] = max(f[i + 1][j + k], f[i][j] + gpa[k]);
g[i + 1][j + k] = min(g[i + 1][j + k], g[i][j] + gpa[k]);
}
}
} int _;RD(_);
while (_--) {
int k, n;
scanf("%d%d",&k,&n);
printf("%.4lf %.4lf\n",g[n][n * k]/(double)n ,f[n][n * k ]/(double)n);
}
return 0;
}