【HDOJ 4968】 Improving the GPA

【HDOJ 4968】 Improving the GPA

动态规划里的背包问题。。比赛时候暴力做的 还好当时脑洞足。。。

暴力枚举

求最大值时初始n个成绩都为最大值所需的最小成绩–85 然后从第一个开始减 分数全都用掉时跳出 第一个减到60后第二个开始 以此类推

求最小值反向做即可 初始为最小值所需的最大成绩–64

背包方法 一维为当前成绩类数 二位为当前使用掉的分数(减去60 因为最小分为60 60之前都是无用空间)

初始dpmax -INF dpmin INF

dpmax[0][0] = dpmin[0][0] = 0;

for i 1->n

for j 0->40

for k 0->v

dpmax = max(dpmax[i][j],dpmax[i-1][j-k] + get(k));

dpmin = min(dpmin[i][j],dpmin[i-1][j-k] + get(k));

代码如下:

//暴力枚举
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>

using namespace std;

double Min(int x,int k)
{
    if(x <= 69) return 2.0;
    int i,j,rest = (x - 69)*k;
    double sum = 2.0*k;

    for(i = 1; i <= k; ++i)
    {
        for(j = 0; j < 3; ++j)
        {
            sum += 0.5;
            if(rest <= 5) return sum/k;
            rest -= 5;
        }
        sum += 0.5;
        if(rest <= 16) return sum/k;
        rest -= 16;
    }
}

double Max(int x,int k)
{
    if(x >= 85) return 4.0;
    int i,j,rest = (85 - x)*k;
    double sum = 4.0*k;

    for(i = 1; i <= k; ++i)
    {
        for(j = 0; j < 3; ++j)
        {
            sum -= 0.5;
            if(rest <= 5) return sum/k;
            rest -= 5;
        }
        sum -= 0.5;
        if(rest <= 10) return sum/k;
        rest -= 10;
    }
}

int main()
{
    int t,x,i,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&x,&k);
        printf("%.4lf ",Min(x,k));
        printf("%.4lf\n",Max(x,k));
    }
    return 0;
}
//dp背包
#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 0x3f3f3f3f

using namespace std;

double dp1[11][405],dp2[11][405];

double get(int k)
{
    return (k <= 9)? 2.0 : (k <= 14? 2.5: (k <= 19? 3.0: (k <= 24?  3.5: 4.0)));
}

void Minx(int v,int n)
{
    int i,j,k;
    for(i = 0; i <= n; ++i)
    {
        for(j = 0; j <= v*n; ++j)
        {
            dp1[i][j] = INF;
            dp2[i][j] = -INF;
        }
    }
    dp1[0][0] = dp2[0][0] = 0;
    for(i = 1; i <= n; ++i)
    {
        for(k = 0; k <= 40 ; ++k)
        {
            for(j = 0; j +k <= v*i; ++j)
            {
                dp1[i][j+k] = min(dp1[i][j+k],dp1[i-1][j] + get(k));
                dp2[i][j+k] = max(dp2[i][j+k],dp2[i-1][j] + get(k));
            }
        }
    }
}

int main()
{
    int t,v,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&v,&n);
        v = (v-60);
        Minx(v,n);
        printf("%.4lf %.4lf\n",dp1[n][v*n]/n,dp2[n][v*n]/n);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-24 23:57:34

【HDOJ 4968】 Improving the GPA的相关文章

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ 5384】Danganronpa

[HDOJ 5384]Danganronpa AC自动机...当时感觉用字典树 标神也往自动机想来着..手太生加上时间紧迫也没敲--回来一看题解什么AB同时建自动机...顿时愣了 什么叫同时建= =问了问财神说普通自动机...B串单建 立马疯了--这不就是模板题么... B串建自动机 A串枚举查询 写完兴冲冲1T--立马想法优化 建fail时压缩一下 查询时直接累计 不再循环找fail 171ms...第二个自动机的题..距上次蛮久了 这次一复习 感觉印象差不多有了 代码(模板)如下: #inc

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

[HDOJ 4686] Arc of Dream (矩阵快速幂) 两个公式 a(i) = a(i-1)*Ax+Ay b(i) = b(i-1)*Bx+By 求 0~(n-1) 的a(i)*b(i) 初始矩阵为                                       求幂矩阵为 a0                                                      Ax          0           0          0        

【HDOJ 1005】 CRB and His Birthday

[HDOJ 1005] CRB and His Birthday 背包 商场卖东西 没件物品有对应的价值 同时由于超市老板跟你是好绩优...每买一件物品给你a个糖果 同时如果购买某物品 会给对应的b种糖果 即买x个i 可以得到ai*x+bi个糖果 问怎么能得到最多糖果 开始是想开个bool标记每个状态某糖果买每买 还有在该状态是否第一次买某种糖果 写着写着写不好了-- 后来突然想到 可以把每件物品拆开 由于每种物品只赠送一次b 可以把赠b的物品作为"特卖品" 其余为正常送a的物品 这样

【HDOJ 4970】 Killing Monsters

[HDOJ 4970] Killing Monsters 数据很大 立马想预处理 每只怪物会从点x出现移动到点n(终点) 问能剩几只怪物 预处理求出每个位置到终点所受伤害 出现一只怪物直接判断死活即可 代码如下: #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <queue>

【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)

pid=5654">[HDOJ 5654] xiaoxin and his watermelon candy(离线+树状数组) xiaoxin and his watermelon candy Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 233    Accepted Submission(s): 61 Problem Des