题意:

  有n道题目,每道题目的初始分数为Ai,分数每分钟减少Bi,完成此题需要Ci分钟,问在t分钟内最多能获得多少分?

思路:

  好题~

  如果没有B的话,就是一道裸的01背包的题目了。每道题目的得分为:v=A-B*g  (其中g为完成这道题目的时刻),想要用背包解的话是可以的,但是完成的次序不同的话,得分也可能受到影响。那就排个序得了,问题在于如何排序?假设已经确定要做哪些题了,则如果交换了相邻两道题的位置,对总分数是有益的,那么肯定是换了,而且他们对其他的题目完全无影响,不妨假设只有两道题要完成,现在要决定他们的完成次序。假设先完成题目1,再完成题目2,设t=C1+C2,那么总分为v1=A1-B1*C1 + A2-B2*t;如果交换次序,则总分为v2=A2-B2*C2 + A1-B1*t,那么v1<=v2时,明显有必要交换位置。

  由v1<=v2得到   A1-B1*C1 + A2-B2*t <= A2-B2*C2 + A1-B1*t

  化简得到 B1*C1 + B2*t >= B2*C2 + B1*t

  那么在排序时直接用这条式子就行了。

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define back que[rear-1]
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
struct node
{
int a, b, c;
double rate;
}seq[N];
int n, time, dp[N*];
int cmp(node a,node b)
{
int t2=a.c+b.c;
return b.b*b.c+a.b*t2>=a.b*a.c+b.b*t2;
}
int cal()
{
sort(seq+,seq+n+, cmp);
memset(dp,-,sizeof(dp));
dp[]=;
for(int i=; i<=n; i++)
for(int j=time; j>=seq[i].c; j--)
{
if( dp[j-seq[i].c]< ) continue;
int v=seq[i].a - j*seq[i].b;
dp[j]=max( dp[j], dp[j-seq[i].c]+v );
}
int ans=;
for(int i=time; i>=; i--)
ans=max(ans, dp[i]);
return ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t;cin>>t;
while(t--)
{
scanf("%d%d",&n,&time);
for(int i=; i<=n; i++)
scanf("%d%d%d", &seq[i].a,&seq[i].b,&seq[i].c);
cout<<cal()<<endl;
}
return ;
}

AC代码

用官方题解的代码:

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define back que[rear-1]
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=;
struct node
{
int a, b, c;
double rate;
}seq[N];
int n, time, dp[N*];
int cmp(node a,node b)
{
return a.rate>b.rate;
}
int cal()
{
sort(seq+,seq+n+, cmp);
memset(dp,-,sizeof(dp));
dp[]=;
for(int i=; i<=n; i++)
for(int j=time; j>=seq[i].c; j--)
{
if( dp[j-seq[i].c]< ) continue;
int v=seq[i].a - j*seq[i].b;
dp[j]=max( dp[j], dp[j-seq[i].c]+v );
}
int ans=;
for(int i=time; i>=; i--)
ans=max(ans, dp[i]);
return ans;
} int main()
{
//freopen("input.txt", "r", stdin);
int t;cin>>t;
while(t--)
{
scanf("%d%d",&n,&time);
for(int i=; i<=n; i++)
{
scanf("%d%d%d", &seq[i].a,&seq[i].b,&seq[i].c);
seq[i].rate=1.0*seq[i].b/seq[i].c;
}
cout<<cal()<<endl;
}
return ;
}

AC代码

HDU 5501 The Highest Mark (贪心+DP,经典)的更多相关文章

  1. HDU 5501 The Highest Mark 背包dp

    The Highest Mark Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  2. HDU 5501 The Highest Mark

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5501 The Highest Mark  Accepts: 32  Submissions: 193 ...

  3. HDU 5501——The Highest Mark——————【贪心+dp】

    The Highest Mark Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  4. hdu 5501 The Highest Mark(贪心+01背包)

    题意:类似cf的赛制,每道题目有A,B,C三个值,A表示初始分数,B表示每分钟题的分数会减少B,C表示做这道题需要C分钟,数据保证分数不会变为负数.现在给出比赛时长,问安排做题的顺序,求最大得分. 思 ...

  5. HDU 5501:The Highest Mark 01背包

    The Highest Mark  Accepts: 71  Submissions: 197  Time Limit: 2000/1000 MS (Java/Others)  Memory Limi ...

  6. HDU5501/BestCoder Round #59 (div.2)The Highest Mark dp+贪心

    The Highest Mark 问题描述 2045年的SD省队选拔,赛制和三十年前已是完全不同.一场比赛的比赛时间有 tt 分钟,有 nn 道题目. 第 ii 道题目的初始分值为 A_i(A_i \ ...

  7. HDU 2993 MAX Average Problem(斜率DP经典+输入输出外挂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给出n,k,给定一个长度为n的序列,从其中找连续的长度大于等于k的子序列使得子序列中的 ...

  8. hdu 1257 最少拦截系统【贪心 || DP——LIS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  9. hdu5501 The Highest Mark

    Problem Description The SDOI in 2045 is far from what it was been 30 years ago. Each competition has ...

随机推荐

  1. STM in Clojure

    Transactional memory in Clojure is implemented using Multiversion Concurrency Control protocol http: ...

  2. 判断ip地址是否为内网ip或局域网ip

    bool IsLanIp(string& ip) { ,) == ,) == ,) == "192.") { return true; } else { return fa ...

  3. Codevs 1159 最大全0子矩阵

    1159 最大全0子矩阵  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 在一个0,1方阵中找出其中最大的全 ...

  4. NFS服务及DHCPD服务

    NFS 服务 Linux与Linux之间的文件共享 就是网络文件系统,依靠网络. 所有端口都存放在此,对应的服务跟端口 cat /etc/service 部署NFS 先部署服务器端: 部署之前要先启用 ...

  5. 1、CreateJS介绍-EaselJS

    需要在html5文件中引入的CreateJS库文件是easeljs-0.7.1.min.js HTML5文件如下: <!DOCTYPE html> <html lang=" ...

  6. CodeForces - 796B-Find The Bone(模拟)

    Zane the wizard is going to perform a magic show shuffling the cups. There are n cups, numbered from ...

  7. Sonya and Matrix Beauty Codeforces - 1080E

    https://codeforces.com/contest/1080/problem/E 比赛时候一个多小时码不出来... 来看遇到的困难: 1.没有能用的随机unsignedlonglong函数 ...

  8. shell 经典

    使用新写法 这里的新写法不是指有多厉害,而是指我们可能更希望使用较新引入的一些语法,更多是偏向代码风格的,比如 尽量使用func(){}来定义函数,而不是func{} 尽量使用[[]]来代替[] 尽量 ...

  9. JAVA_HOME not recognized by tomcat7 in Ubuntu

    vi .bashrc 添加: export JAVA_HOME=/usr/lib/jvm/java--oracle export JRE_HOME=$JAVA_HOME/jre export CLAS ...

  10. 机器学习框架ML.NET学习笔记【5】多元分类之手写数字识别(续)

    一.概述 上一篇文章我们利用ML.NET的多元分类算法实现了一个手写数字识别的例子,这个例子存在一个问题,就是输入的数据是预处理过的,很不直观,这次我们要直接通过图片来进行学习和判断.思路很简单,就是 ...