我是题面

恩,贪心,鉴定完毕。

一个物品是否放进来,取决于它是否能对答案做出贡献。

那物品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 最大收益的更多相关文章

  1. 洛谷P2647 最大收益

    P2647 最大收益 题目描述 现在你面前有n个物品,编号分别为1,2,3,……,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的 ...

  2. 洛谷—— P2647 最大收益

    https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,……,n.你可以在这当中任意选择任意多个物品.其中第i个物 ...

  3. 洛谷 P2647 最大收益 题解

    题面 对于“n个物品选任意个”我们就可以想到一种递推方法,即设f[i][j]表示前i个物品选j个的最大收益 我们发现正着转移并不好转移,我们可以倒着转移,使选择的当前第i号物品为第一个物品,这样的话我 ...

  4. 【洛谷P2647】最大收益

    题目大意 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的收益:但是,你选择该物 ...

  5. 洛谷P4307 球队收益

    题意:有n个球队,m场比赛. 每个球队都已经有些胜负场次了. 每个球队的收益为Ci * wini2 - Di * losei2. 求最小可能总收益. 解: 先看出一个模型:用一流量代表一个胜场,每场比 ...

  6. 洛谷 P3410 拍照

    洛谷 P3410 拍照 题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. ...

  7. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  8. 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码

    洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...

  9. BZOJ1855或洛谷2569 [SCOI2010]股票交易

    一道单调队列优化\(DP\) BZOJ原题链接 洛谷原题链接 朴素的\(DP\)方程并不难想. 定义\(f[i][j]\)表示到第\(i\)天,手上持有\(j\)股时的最大收益. 转移方程可以分成四个 ...

随机推荐

  1. 4825: [Hnoi2017]单旋

    4825: [Hnoi2017]单旋 链接 分析: 以后采取更保险的方式写代码!!!81行本来以为不特判也可以,然后就总是比答案大1,甚至出现负数,调啊调啊调啊调~~~ 只会旋转最大值和最小值,以最小 ...

  2. Session丢失——解决方案

    先抄下别人的作业(原帖:http://www.cnblogs.com/zhc088/archive/2011/07/24/2115497.html) Session丢失已经是一种习以为常的问题了,在自 ...

  3. 理解依赖注入(Dependency Injection)

    理解依赖注入 Yii2.0 使用了依赖注入的思想.正是使用这种模式,使得Yii2异常灵活和强大.千万不要以为这是很玄乎的东西,看完下面的两个例子就懂了. class SessionStorage { ...

  4. MSP-EZ430U_02板子测试使用

    1. 实物如下 2. 先上电,显示驱动没安装 3. 找到驱动的位置,不过实际上安装IAR for msp430之后,驱动就自动的识别了.

  5. MySQL授权root

    1. 改表法. 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 " ...

  6. js文件上传库

    收集了2个与具体UI库和框架无任何耦合的JS文件上传库:支持断点续传.支持npm安装. resumable.js fileapi

  7. Java构造方法与析构方法实例剖析

    Java构造方法 类有一个特殊的成员方法叫作构造方法,它的作用是创建对象并初始化成员变量.在创建对象时,会自动调用类的构造方法. 构造方法定义规则:Java 中的构造方法必须与该类具有相同的名字,并且 ...

  8. 人脸检测及识别python实现系列(3)——为模型训练准备人脸数据

    人脸检测及识别python实现系列(3)——为模型训练准备人脸数据 机器学习最本质的地方就是基于海量数据统计的学习,说白了,机器学习其实就是在模拟人类儿童的学习行为.举一个简单的例子,成年人并没有主动 ...

  9. Siki_Unity_2-3_UGUI_Unity4.6 UI Beta版本入门学习(未学)

    Unity 2-3 UGUI Unity4.6 UI Beta版本入门学习(未学)

  10. PPM、PGM、PBM图像格式剖析

    今天突然需要用到PPM这个图像文件格式,之前没见过,在此记录一下. PPM.PGM.PBM这三个图像文件格式很少见,其实也不难,分别用于彩色图像.灰度图像.二值图像.这里以PPM格式为例. PPM格式 ...