HDU5501/BestCoder Round #59 (div.2)The Highest Mark dp+贪心
2015-10-11 12:05
357 查看
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
Hint
dxy先做第二题,再做第一题,第一题得分为110-5*(1+9)=60110−5∗(1+9)=60,第二题得分为30-2*1=2830−2∗1=28,总得分为8888,其他任何方案的得分都小于8888 题解:考虑a,b; 如果先a后b A1-B1*C1+A2-(C1+C2)*B2 如果先b后a A2-B2*C2+A1-(C1+C2)*B1 化简得B2C1<B1C2这种排序方法可行 再背包一下就好了 转移方程为 dp[j-a[i].C]=max(dp[j-a[i].C],dp[j]+a[i].A-(t-(j-a[i].C))*a[i].B);
///1085422276 #include<bits/stdc++.h> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define TS printf("111111\n"); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a,b,c) scanf("%d%d%d",&a,&b,&c) #define inf 100000 inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } //**************************************** #define maxn 3000+5 int dp[maxn]; struct ss { int A,B,C; }a[maxn]; int cmp(ss s1,ss s2) { return s1.C*s2.B<s1.B*s2.C; } int main() { int T=read(); while(T--) { int n=read(); int t=read(); FOR(i,1,n) { scanf("%d%d%d",&a[i].A,&a[i].B,&a[i].C); } sort(a+1,a+n+1,cmp); mem(dp); /* for(int i=0;i<=t;i++) dp[i][0]=0; for(int i=1;i<=n;i++) dp[C[i]][1]=A[i]-C[i]*B[i];*/ for(int i=1;i<=n;i++) { for(int j=a[i].C;j<=t;j++) { dp[j-a[i].C]=max(dp[j-a[i].C],dp[j]+a[i].A-(t-(j-a[i].C))*a[i].B); } } int ans=-1; for(int i=0;i<=t;i++)ans=max(dp[i],ans); cout<<ans<<endl; } return 0; }daima
相关文章推荐
- C#使用基类的引用 and 虚方法和覆写方法
- 定时自动启动任务crontab命令用法
- 条件编译(#ifdef #else #endif #if)
- C#内存管理-栈堆/回收器托管/非托管资源释放/指针的应用
- 【小白装系统】——U盘法简介
- BZOJ 1061: [Noi2008]志愿者招募(最小费用最大流)
- 分西瓜(DFS)
- iOS_Quartz 2D绘图
- PHP计划任务:如何使用Linux的Crontab执行PHP脚本
- win 10 右键新建offic失效问题
- iOS 视频播放基础
- 服 务 器 时 间 设 置
- eclipse中文乱码修改新方法,在修改了所有的utf-8都没有用就这样修改
- python 环境的配置和pip 的安装
- 互联网的地位
- 互联网的地位
- C++ TCp通信遇到的无法解析外部符号
- 20151011112722实验
- java 枚举
- Linux安全性模型及权限详细