洛谷 P2647 最大收益
恩,贪心,鉴定完毕。
一个物品是否放进来,取决于它是否能对答案做出贡献。
那物品i的贡献就是\(w[i]-r[i]\)
可是收益的减少是会叠加的
那就是\(w[i]-j*r[i]\),j表示选择物品i后又选择的物品数量
可是我怎么知道选择i后又会选择几件物品啊
那么我们引入一个新的值\(d[i]=w[i]/r[i]\),表示若使物品i对答案有贡献,选择物品i后最多再选择d件物品
既然这样,我们也有点眉目了,dfs啊
很好,写的很漂亮,50。。。TLE
dfs
看来是不能再优化了
那让我们退回去,往前看“可是我怎么知道选择i后又会选择几种物品啊”
好像有一种方法可以知道还会再选几件,没错,你是不是也想到了,就是 dfs 动规
我们用\(f[i][j]\)表示在前i种物品中选择j件,可是这怎么记忆之前所说的j呢?
还记得之前说好的贪心吗,这里继续贪。
我们把物品按照r从大到小的顺序排序,\(f[i][j]\)表示i件物品选择j件且最先选择j件时的收益
这里的贪心很好证明,既然r要取多次,那么我们自然默认让更小的r选择更多的次数
下面是代码
dfs版
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc() getchar()
#define maxn 3005
using namespace std;
inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}
void write(ll a){
if(a>9)write(a/10);
putchar(a%10+'0');
}
int n;
struct ahaha{
int w,r,d;
friend bool operator < (ahaha x,ahaha y){
return x.d>y.d;
}
}a[maxn];
bool c[maxn]; //表示物品是否被选择过
int ans;
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
void dfs(int sum,int sr,int sy){ //sum表示当前收益,sr表示需要累计下去的r,sy表示最多还能选择sy个数贪心就不优了
ans=max(ans,sum); //因为不知道选多少个数,所以ans每步比较
if(!sy)return; //如果不能再选 返回
for(int i=1;i<=n;++i){
if(c[i])continue;
c[i]=1;
dfs(sum+a[i].w-sr,sr+a[i].r,min(sy-1,a[i].d)); //sy应取最小值
c[i]=0;
}
}
inline void solve(){
for(int i=1;i<=n;++i){
c[i]=1;
dfs(a[i].w,a[i].r,a[i].d);
c[i]=0;
}
}
int main(){
n=read();
for(int i=1;i<=n;++i)a[i].w=read(),a[i].r=read(),a[i].d=a[i].w/a[i].r;
sort(a+1,a+n+1);
solve();
write(ans);
return 0;
}
DP版
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc() getchar()
#define maxn 3005
using namespace std;
inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
}
void write(ll a){
if(a>9)write(a/10);
putchar(a%10+'0');
}
int n,f[maxn][maxn],ans;
struct ahaha{
int w,r;
friend bool operator < (ahaha x,ahaha y){
return x.r>y.r;
}
}a[maxn];
int main(){
n=read();
for(int i=1;i<=n;++i)a[i].w=read(),a[i].r=read();
sort(a+1,a+n+1);
f[1][1]=a[1].w;
for(int i=2;i<=n;++i)
for(int j=1;j<=i;++j)
f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i].w-a[i].r*(j-1)); //表示选择i个物品时,选择物品i和不选物品i两种操作
for(int i=1;i<=n;++i)ans=max(ans,f[n][i]);
write(ans);
return 0;
}
洛谷 P2647 最大收益的更多相关文章
- 洛谷P2647 最大收益
P2647 最大收益 题目描述 现在你面前有n个物品,编号分别为1,2,3,……,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的 ...
- 洛谷—— P2647 最大收益
https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,……,n.你可以在这当中任意选择任意多个物品.其中第i个物 ...
- 洛谷 P2647 最大收益 题解
题面 对于“n个物品选任意个”我们就可以想到一种递推方法,即设f[i][j]表示前i个物品选j个的最大收益 我们发现正着转移并不好转移,我们可以倒着转移,使选择的当前第i号物品为第一个物品,这样的话我 ...
- 【洛谷P2647】最大收益
题目大意 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的收益:但是,你选择该物 ...
- 洛谷P4307 球队收益
题意:有n个球队,m场比赛. 每个球队都已经有些胜负场次了. 每个球队的收益为Ci * wini2 - Di * losei2. 求最小可能总收益. 解: 先看出一个模型:用一流量代表一个胜场,每场比 ...
- 洛谷 P3410 拍照
洛谷 P3410 拍照 题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码
洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...
- BZOJ1855或洛谷2569 [SCOI2010]股票交易
一道单调队列优化\(DP\) BZOJ原题链接 洛谷原题链接 朴素的\(DP\)方程并不难想. 定义\(f[i][j]\)表示到第\(i\)天,手上持有\(j\)股时的最大收益. 转移方程可以分成四个 ...
随机推荐
- Angular ng-include 学习实例
ng-include 可以引入外部的文件到当前视图中.这样可以增强复用性. 最简单的用法 <div ng-include src="'/public/template/tpl.htm ...
- cogs1713 [POJ2774]很长的信息
cogs1713 [POJ2774]很长的信息 原题链接 题解 把两串拼成A+'%'+B+'$'.跑后缀数组然后相邻两点i,i+1不在同一串里就用ht[i]更新答案. 好裸... Code // It ...
- pyhon3.0 day01 变量、输入、输出、循环
pyhon3.0 基础01 1 python解释器 Python的解释器很多,但使用最广泛的还是CPython.如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython, ...
- ----------BMI指数小程序----------
# 1.创建并输出菜单, 菜单是不可变的. 所以使用元组# menus = ("1, 录入", "2, 查询", "3, 删除", &quo ...
- Qt 利用XML文档,写一个程序集合 二
接上一篇文章https://www.cnblogs.com/DreamDog/p/9213915.html XML文档的读写 一个根节点,下面每一个子节点代表一个子程序,内容为子程序名字,图标路径,e ...
- 解决Sublime Text 3中文显示乱码(tab中文方块)问题
博客分类: Sublime 一.文本出现中文乱码问题 1.打开Sublime Text 3,按Ctrl+-打开控制行,复制粘贴以下python代码,然后回车运行. 2. 复制并粘贴如下代码: P ...
- tomcat配置https | 自签发证书配置
未配置证书的访问:
- Scala基础知识笔记1
上一篇文章介绍了如何下载scala, 因为在官网上点击下载按钮无法下载, 下面介绍scala的基础语法: 1 scala和java的关系 Scala是基于jvm的一门编程语言,Scala的代码最终会经 ...
- cinder的组件
跟nova相似,cinder也有很多组件,每个组件负责各自的业务,然后共同协作完成volume的管理.组件之间的通信方式与nova个组件之间的通信方式相同,都是通过消息队列进行通信. cinder-a ...
- python基础知识-7-内存、深浅、文件操作
python其他知识目录 1.一些对内存深入理解的案例 以下列举列表,列表/字典/集合这些可变类型都是一样的原理 变量是个地址,指向存储数据的内存空间的地址,它的实质就相当于c语言里的指针.变量和数据 ...