自爆魂

博客园 首页 新随笔 联系 订阅 管理

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


posted on 2014-10-21 11:14  自爆魂  阅读(151)  评论(0编辑  收藏  举报