HDU 5501 The Highest Mark
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5501
The Highest Mark
2045年的SD省队选拔,赛制和三十年前已是完全不同。一场比赛的比赛时间有 tt 分钟,有 nn 道题目。
第 ii 道题目的初始分值为 A_i(A_i \leq 10^{6})Ai(Ai≤106) 分,之后每过一分钟这道题目的分值会减少 B_iBi 分,并且保证到比赛结束时分值不会减少为负值。比如,一个人在第 xx 分钟结束时做出了第 ii 道题目,那么他/她可以得到 A_i - B_i * xAi−Bi∗x 分。
若一名选手在第 xx 分钟结束时做完了一道题目,则他/她可以在第 x+1x+1 分钟开始时立即开始做另一道题目。
参加省队选拔的选手 dxy 具有绝佳的实力,他可以准确预测自己做每道题目所要花费的时间,做第 ii 道需要花费 C_i(C_i \leq t)Ci(Ci≤t) 分钟。由于 dxy 非常神,他会做所有的题目。但是由于比赛时间有限,他可能无法做完所有的题目。他希望安排一个做题的顺序,在比赛结束之前得到尽量多的分数。
第一行为一个正整数 T(T \leq 10)T(T≤10),表示数据组数(n>200n>200的数据不超过55组)。
对于每组数据,第一行为两个正整数 n (n \leq 1000)n(n≤1000) 和 t (t \leq 3000)t(t≤3000), 分别表示题目数量和比赛时间。接下来有 nn 行,每行 33 个正整数依次表示 A_i, B_i, C_iAi,Bi,Ci,即此题的初始分值、每分钟减少的分值、dxy做这道题需要花费的时间。
对于每组数据输出一行一个整数,代表dxy这场比赛最多能得多少分
1
4 10
110 5 9
30 2 1
80 4 8
50 3 2
88
dxy先做第二题,再做第一题,第一题得分为110-5*(1+9)=60110−5∗(1+9)=60,第二题得分为30-2*1=2830−2∗1=28,总得分为8888,其他任何方案的得分都小于8888
题解:
贪心+01背包。
贪心:
假设比赛时间无限大,每一道题目都能做完,那么你按照bi/ci由大到小排序的顺序完成所有题目会得到优成绩,
为什么呢?
任意两个相邻的题目i和j(i<j),先做i,你会多损失分数:ci*bj;先做j,你会多损失cj*bi,如果我们要先完成i,则有ci*bj<=cj*bi,即bi/ci>=bj/cj。
现在考虑有限时间内,如果最优解中的几个问题不是按照这个顺序来完成的,那么我们经过以上操作调整之后能使损失减小,从而得到更优解。
所以这个贪心是正确的。
dp:
贪心完之后,跑一遍01背包就可以了。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ;
const int maxt = ; struct Node {
int a, b, c;
bool operator < (const Node& tmp) {
return b*tmp.c>c*tmp.b;
}
}node[maxn]; int N, T;
int dp[maxn][maxt]; int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &N, &T);
for (int i = ; i <= N; i++) {
scanf("%d%d%d", &node[i].a, &node[i].b, &node[i].c);
}
sort(node + , node + N + );
/*
for(int i = 1; i <= N; i++) printf("%d ", node[i].a);
printf("\n");
*/
memset(dp[], , sizeof(dp[]));
for (int i = ; i <= N; i++) {
for (int j = ; j < node[i].c; j++) dp[i][j] = dp[i - ][j];
for (int j = node[i].c; j <= T; j++) {
dp[i][j] = max(dp[i - ][j], dp[i - ][j - node[i].c]+node[i].a-node[i].b*j);
}
}
int ans = ;
for (int i = ; i <= T; i++) ans = max(ans, dp[N][i]);
printf("%d\n", ans);
}
return ;
}
优化:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; const int maxn = ;
const int maxt = ; struct Node {
int a, b, c;
bool operator < (const Node& tmp) {
return b*tmp.c>c*tmp.b;
}
}node[maxn]; int N, T;
int dp[maxt]; int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
scanf("%d%d", &N, &T);
for (int i = ; i <= N; i++) {
scanf("%d%d%d", &node[i].a, &node[i].b, &node[i].c);
}
sort(node + , node + N + );
memset(dp, , sizeof(dp));
for (int i = ; i <= N; i++) {
for (int j = T; j >= node[i].c; j--) {
dp[j] = max(dp[j], dp[j - node[i].c] + node[i].a - node[i].b*j);
}
}
int ans = ;
for (int i = ; i <= T; i++) ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return ;
}
HDU 5501 The Highest Mark的更多相关文章
- 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 ...
- HDU 5501——The Highest Mark——————【贪心+dp】
The Highest Mark Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- hdu 5501 The Highest Mark(贪心+01背包)
题意:类似cf的赛制,每道题目有A,B,C三个值,A表示初始分数,B表示每分钟题的分数会减少B,C表示做这道题需要C分钟,数据保证分数不会变为负数.现在给出比赛时长,问安排做题的顺序,求最大得分. 思 ...
- HDU 5501 The Highest Mark (贪心+DP,经典)
题意: 有n道题目,每道题目的初始分数为Ai,分数每分钟减少Bi,完成此题需要Ci分钟,问在t分钟内最多能获得多少分? 思路: 好题~ 如果没有B的话,就是一道裸的01背包的题目了.每道题目的得分为: ...
- HDU 5501:The Highest Mark 01背包
The Highest Mark Accepts: 71 Submissions: 197 Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...
- The Highest Mark(01背包)
The Highest Mark Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- HDU5501/BestCoder Round #59 (div.2)The Highest Mark dp+贪心
The Highest Mark 问题描述 2045年的SD省队选拔,赛制和三十年前已是完全不同.一场比赛的比赛时间有 tt 分钟,有 nn 道题目. 第 ii 道题目的初始分值为 A_i(A_i \ ...
- hdu5501 The Highest Mark
Problem Description The SDOI in 2045 is far from what it was been 30 years ago. Each competition has ...
- HDU 5501 背包问题
需要按照B/C的值从大到小排序. #include<cstdio> #include<cstring> #include<iostream> #include< ...
随机推荐
- node 借助Node Binary管理模块“n”更新
Node.js的版本频繁变化,如果有模块不能在你当前的Node版本上使用,需要升级Node环境 1)首先:查看当前node版本:node –v 2)安装n模块:npm install -g n 3)检 ...
- 一图看懂JVM,JRE,JDK的关系
- python 运算符与分支结构
运算符与分支结构 运算符 赋值运算符 用'='表示,左边只能是变量 算术运算符 +.-.*:加.减.乘 /:除法运算,结果是浮点型 //:除法运算,结果是整型 %:求余 **:求幂 复合运算符 +=. ...
- SpringBoot 启动报The Java Virtual Machine has not been configured to use the desired default character encoding (UTF-8)
解决方法: 启动的时候在VM中添加 Dfile.encoding=UTF-8 就好了!
- python2.7入门---XML解析
首先我们先来考虑,什么是XML?XML 指可扩展标记语言(eXtensible Markup Language).XML 被设计用来传输和存储数据.XML是一套定义语义标记的规则,这些标记将文 ...
- 一些有趣的 Shell 命令
find . -name "*.db" -type f 查找当前路径下名称满足正则*.db的文件,-type d 则是查找文件夹 grep -rn "Main" ...
- SWT_之Table篇
package edu.ch4; import org.eclipse.swt.SWT;import org.eclipse.swt.events.SelectionAdapter;import or ...
- # 第二周c实践所遇见的问题
第二周c实践所遇见的问题 地址符 在编程练习中时常忘记写入地址符,造成过运行错误,运行结果错误的惨痛教训,一个小小的错误耗费了很长的时间来寻找错误之处,养成写代码的一些好习惯势在必行.牢记scanf( ...
- 【洛谷P4556】 雨天的尾巴
题面 题解 线段树合并 我们看到这道题目首先可以想到树上差分,然后\(dfs\)合并 发现题目让我们求的东西很好用线段树维护 于是可以想到线段树合并 全世界只有我写指针版动态开点线段树(大雾 如果你要 ...
- 1135: [POI2009]Lyz
1135: [POI2009]Lyz https://lydsy.com/JudgeOnline/problem.php?id=1135 分析: hall定理+线段树连续区间的最大的和. 首先转化为二 ...