BC#59 The Highest Mark
2015-10-14 15:09
525 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5501
分析:首先贪心分析。考虑…x1 x2….互换x1x2不影响其他题对答案的贡献,那么得出互换的条件,于是得到结论:按B/C的顺序排序。这里注意,不要写除法,会被卡,分子分母交叉乘起来比较大小。
然后需要一个01背包DP。这题与SD夏令营挂项链一题极为相似,当时我也没有想明白为什么贪心后还要DP,现在终于明白:贪心只是确定了选择的最优顺序,但是并没有决定选哪些,如果贪心依据不包含除法,就不用DP一遍了。
代码:
分析:首先贪心分析。考虑…x1 x2….互换x1x2不影响其他题对答案的贡献,那么得出互换的条件,于是得到结论:按B/C的顺序排序。这里注意,不要写除法,会被卡,分子分母交叉乘起来比较大小。
然后需要一个01背包DP。这题与SD夏令营挂项链一题极为相似,当时我也没有想明白为什么贪心后还要DP,现在终于明白:贪心只是确定了选择的最优顺序,但是并没有决定选哪些,如果贪心依据不包含除法,就不用DP一遍了。
代码:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int Tmax=1005,Tmax2=3005; struct node{ long long int A,B,C; bool operator <(const node &rhs)const { return B*rhs.C>rhs.B*C; } }; node data[Tmax]; int n,t; long long f[Tmax2],ans; void work() { int i,j; for(i=1;i<=n;i++) for(j=t;j>=data[i].C;j--) f[j]=max(f[j],f[j-data[i].C]+max((long long )0,data[i].A-data[i].B*j)); for(i=0;i<=t;i++) ans=max(ans,f[i]); return; } int main() { int T,i; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&t); ans=0; memset(f,0,sizeof(f)); for(i=1;i<=n;i++) scanf("%I64d%I64d%I64d",&data[i].A,&data[i].B,&data[i].C); sort(data+1,data+1+n); work(); printf("%I64d\n",ans); } return 0; }
相关文章推荐
- C# 文件压缩与解压(ZIP格式)
- C# 反射 通过类名创建类实例
- windbg查找c#高内存原因
- C# 生成和读取Xml文档
- C#基础,值类型与引用类型,父类与子类
- (转)用C#一步步写串口通信
- (转)用C#一步步写串口通信
- C#随机数生成
- 检查c#代码内存泄露工具-CLR Profiler
- C# String.Format大全
- [原]C# 读取Word 表格数据(单元格纵合并)
- C#创建不规则窗体的4种方式详解
- C#编程和Visual Studio使用技巧(下)
- C#编程和Visual Studio使用技巧(上)
- [转]C#使用 Salt + Hash 来为密码加密
- C#的异常处理
- C#图片处理3种高级应用
- C#实现任务栏通知窗口
- C# FileStream流文件读写
- C#中this在构造函数时的使用