当前位置: 首页 > news >正文

22牛客多校4 - Task Computing(相邻贪心,推式子倒序DP)

https://ac.nowcoder.com/acm/contest/33189/A

题意
给定长度为 n 的数组 a [ ] a[] a[],每个位置有两个元素 w i ,   p i w_i,\ p_i wi, pi

从中按照任意顺序选出若干个位置 a 1 , a 2 , … , a m ( 1 ≤ a i ≤ n ) a_1, a_2, \ldots, a_m \text (1 \leq a_i \leq n \text ) a1,a2,,am(1ain) ,使得: ∑ i = 1 m w a i ∏ j = 0 i − 1 p a j \sum_{i=1}^m w_{a i} \prod_{j=0}^{i-1} p_{a_j} i=1mwaij=0i1paj 最大。

输出最大值。

1 ≤ n ≤ 1 0 5 ,   1 ≤ m ≤ min ⁡ ( n , 20 ) 1≤n≤10^5,\ 1\le m \le \min(n,20) 1n105, 1mmin(n,20)
1 ≤ w i ≤ 1 0 9 ,   8000 ≤ q i ≤ 12000 ,   p i = 10000 q i 1\le w_i \le 10^9,\ 8000≤q_i≤12000,\ p_i= \frac {10000} {q_i} 1wi109, 8000qi12000, pi=qi10000

思路
首先可以将数组重新排序,然后只需要按照从前往后的顺序挑选若干个位置,使得 a 1 , a 2 , … , a m ( 1 ≤ a i ≤ n ) a_1, a_2, \ldots, a_m \text (1 \leq a_i \leq n \text ) a1,a2,,am(1ain) 最大。
相邻的两项互换位置对其余位置没有影响,而如果交换之后能使结果更优的话就交换,最终能够得到最佳的排列顺序。
只考虑 3 个位置,然后交换后两个位置,比较两个交换之后的答案,得出:如果 w 1 + w 2 ∗ p 1 > w 2 + w 1 ∗ p 2 w_1 + w_2*p_1 > w_2 + w_1*p_2 w1+w2p1>w2+w1p2 时,1 位置放到 2 位置前面更优。按照这个原则将所有位置排序。

然后就是从这 n 个位置中,从前往后依次挑出 m 个位置,使得 a 1 , a 2 , … , a m ( 1 ≤ a i ≤ n ) a_1, a_2, \ldots, a_m \text (1 \leq a_i \leq n \text ) a1,a2,,am(1ain) 最大。

考虑 DP。
一开始可能会这样想:定义 f[i, j] 表示,从前 i 个位置中选出 j 个位置,所得出的结果最大值。
从当前位置选和不选两种状态来转移,如果不选就是 f[i-1, j],如果选便是从 f[i-1, j-1] 转移,同时加上 wi 乘上 f[i-1, j-1] 时 pi 的乘积,所以还要维护出 mul[i, j],表示到达 (i, j) 状态时的 pi 乘积。这样就可以转移了。
但是这样转移是否是正确的呢?
不一定,f[i-1, j-1] 得出的答案是最大的,但是得到这种状态时 pi 的乘积却可能是很小的,那么转移过来的答案和乘积有关系,所以从上个位置的最值转移不一定是最优的。不能这样转移。

没有办法,再化化式子。
如果选了 1,2,3,4 位置,那么最终的答案为:
w 1 + w 2 p 1 + w 3 p 1 p 2 + w 4 p 1 p 2 p 3 w_1 + w_2p_1 + w_3p_1p_2 + w_4p_1p_2p_3 w1+w2p1+w3p1p2+w4p1p2p3
= w 1 + p 1 ( w 2 + w 3 p 2 + w 4 p 2 p 3 ) =w_1 + p_1(w_2 + w_3p_2+w_4p_2p_3) =w1+p1(w2+w3p2+w4p2p3)
= w 1 + p 1 [ w 2 + p 2 ( w 3 + p 3 w 4 ) ] =w_1 + p_1[w_2 + p_2(w_3 + p_3w_4)] =w1+p1[w2+p2(w3+p3w4)]

容易发现,可以从后往前递推: w i + p i ∗ a n s w_i + p_i*ans wi+pians a n s ans ans 为后一位置递推的答案。

所以可以从后往前 DP。
f[i, j] 表示,从 i 位置到 n 位置中选出 j 个位置,答案的最大值。
f[i, j] = max(f[i+1, j], wi + pi*f[i+1, j-1])

Code

#include<bits/stdc++.h>
using namespace std;

#define Ios ios::sync_with_stdio(false),cin.tie(0)
#define int long long
#define endl '\n'

const int N = 200010, mod = 1e9+7;
int T, n, m;
struct node{
	int w;
	double p;
}a[N];
double f[N][21];

bool cmp(node a, node b){
	return a.w + b.w*a.p > b.w + a.w*b.p;
}

signed main(){
	Ios;
	cin >> n >> m;
	for(int i=1;i<=n;i++) cin >> a[i].w;
	for(int i=1;i<=n;i++){
		cin >> a[i].p;
		a[i].p = a[i].p/10000;
	}
	
	sort(a+1, a+n+1, cmp);
	
	for(int i=n;i>=1;i--)
	{
		for(int j=1;j<=min(n-i+1, m);j++)
		{
			f[i][j] = max(f[i+1][j], a[i].w + a[i].p * f[i+1][j-1]);
		}
	}
	printf("%.10f", f[1][m]);
	
	return 0;
}

还需要注意的是,题目给出的 p i p_i pi 是乘以 10000 之后的,一开始先没有除以 10000,觉得乘以 10000 对排序没有影响,想着最后转移的时候再除,减少精度误差,其实这样是对排序有影响的,排序是按照 wi + wj*pi 的,还加上一个值,等式两边不能同时约去 10000,会出现错误!
所以要先提前除过来。

相关文章:

  • LLVM学习入门(2):实现解析器 Parser 和语法树 AST
  • Spring Cloud项目(七)——使用sentinel作为熔断降级
  • 轻量应用服务器vs云服务器:区别在哪?
  • javascript中BOM对象
  • android的本地通讯录获取以及RecyclerView展示
  • 大学生任务app软件开发功能介绍
  • 3天精通Postman---动态参数amp;断言amp;CSV数据驱动amp;Mock Server
  • 【面试题】线程池
  • 大学生手机兼职小程序APP开发
  • 20 C++设计模式之迭代器(Iterator)模式
  • Redis自动过期机制之key的过期监听
  • 闲鱼转转源码完整版
  • 企业文档管理系统B/S、C/S架构分别有哪些优劣势?
  • J9数字论:关于区块链的那些专业术语
  • 跨境电商旺季来临,做好这8点爆单不用愁
  • ERLANG 网工修炼笔记 ---- UDP
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Linux快速复制或删除大量小文件
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Protobuf3语言指南
  • Vim Clutch | 面向脚踏板编程……
  • zookeeper系列(七)实战分布式命名服务
  • 初识 beanstalkd
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 关于使用markdown的方法(引自CSDN教程)
  • 解决iview多表头动态更改列元素发生的错误
  • 利用DataURL技术在网页上显示图片
  • 每天10道Java面试题,跟我走,offer有!
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 试着探索高并发下的系统架构面貌
  • 微服务核心架构梳理
  • 原生JS动态加载JS、CSS文件及代码脚本
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • #Ubuntu(修改root信息)
  • (42)STM32——LCD显示屏实验笔记
  • (Python第六天)文件处理
  • (二)换源+apt-get基础配置+搜狗拼音
  • (一)VirtualBox安装增强功能
  • (转载)深入super,看Python如何解决钻石继承难题
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .apk文件,IIS不支持下载解决
  • .net framework 4.0中如何 输出 form 的name属性。
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .net 受管制代码
  • .Net程序帮助文档制作
  • .NET基础篇——反射的奥妙
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .考试倒计时43天!来提分啦!
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @angular/cli项目构建--http(2)
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @property python知乎_Python3基础之:property
  • [ SNOI 2013 ] Quare
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证