传送门

题意:nnn个物品,有aaa个XXX道具和bbb个YYY道具,XXX道具移走第iii个物品概率为pip_ipi​,YYY道具移走第iii个道具概率为uiu_iui​。

对于每个物品每种道具最多用一次且只能被移走一次,现在问对于道具的所有分配方案中移走物品的总个数的期望最大值是多少。


思路:

有一个很显然的O(n3)dp:fi,j,kO(n^3)dp:f_{i,j,k}O(n3)dp:fi,j,k​表示前iii个物品用jjj个XXX道具和kkk个YYY道具的最大期望。

然后暴力代码如下:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=205;
int n,a,b;
double p[N],u[N],f[N][N][N];
int main(){
	n=read(),a=read(),b=read();
	for(ri i=1;i<=n;++i)scanf("%lf",&p[i]);
	for(ri i=1;i<=n;++i)scanf("%lf",&u[i]);
	for(ri i=1;i<=n;++i){
		for(ri j=0;j<=a;++j)for(ri k=0;k<=b;++k){
			f[i][j][k]=f[i-1][j][k];
			if(j)f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]+p[i]);
			if(k)f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+u[i]);
			if(j&&k)f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]+1-(1-p[i])*(1-u[i]));
		}
	}
	printf("%.6lf",f[n][a][b]);
	return 0;
}

然而这显然是不够优秀的

因此我们发现可以对后两维都进行一次凸优化,复杂度O(nlogn2)O(nlog_n^2)O(nlogn2​)

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const double eps=1e-8;
const int N=2005;
int n,a,b;
double p[N],u[N];
struct data{
	double v;
	int a,b;
	data(double v=0,int a=0,int b=0):v(v),a(a),b(b){}
	friend inline data operator+(const data&a,const data&b){return data(a.v+b.v,a.a+b.a,a.b+b.b);}
}f[N];
inline void solve(double w1,double w2){
	f[0]=data(0,0,0);
	for(ri i=1;i<=n;++i){
		f[i]=f[i-1];
		if(f[i-1].v+p[i]-w1>f[i].v)f[i]=f[i-1]+data(p[i]-w1,1,0);
		if(f[i-1].v+u[i]-w2>f[i].v)f[i]=f[i-1]+data(u[i]-w2,0,1);
		if(f[i-1].v+p[i]+u[i]-p[i]*u[i]-w1-w2>f[i].v)f[i]=f[i-1]+data(p[i]+u[i]-p[i]*u[i]-w1-w2,1,1);
	}
}
int main(){
	n=read(),a=read(),b=read();
	for(ri i=1;i<=n;++i)scanf("%lf",&p[i]);
	for(ri i=1;i<=n;++i)scanf("%lf",&u[i]);
	double l1=0,r1=1,l2,r2;
	while(r1-l1>=eps){
		double mid1=(l1+r1)/2;
		l2=0,r2=1;
		while(r2-l2>=eps){
			double mid2=(l2+r2)/2;
			solve(mid1,mid2);
			f[n].b>b?l2=mid2:r2=mid2;
		}
		solve(mid1,r2);
		f[n].a>a?l1=mid1:r1=mid1;
	}
	solve(r1,r2);
	printf("%.6lf",f[n].v+r1*a+r2*b);
	return 0;
}

2019.03.12 codeforces739E. Gosha is hunting(dp凸优化)的更多相关文章

  1. 【Codeforces 321E / BZOJ 5311】【DP凸优化】【单调队列】贞鱼

    目录 题意: 输入格式 输出格式 思路: DP凸优化的部分 单调队列转移的部分 坑点 代码 题意: 有n条超级大佬贞鱼站成一行,现在你需要使用恰好k辆车把它们全都运走.要求每辆车上的贞鱼在序列中都是连 ...

  2. 「学习笔记」wqs二分/dp凸优化

    [学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...

  3. dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)

    qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...

  4. CF739E Gosha is hunting DP+wqs二分

    我是从其他博客里看到这题的,上面说做法是wqs二分套wqs二分?但是我好懒呀,只用了一个wqs二分,于是\(O(nlog^2n)\)→\(O(n^2logn)\) 首先我们有一个\(O(n^3)\)的 ...

  5. Codeforces.739E.Gosha is hunting(DP 带权二分)

    题目链接 \(Description\) 有\(n\)只精灵,两种精灵球(高级和低级),每种球能捕捉到第\(i\)只精灵的概率已知.求用\(A\)个低级球和\(B\)个高级球能捕捉到精灵数的最大期望. ...

  6. Codeforces739E Gosha is hunting

    题意:现在有n个精灵,两种精灵球各m1和m2个,每个精灵单独使用第一种精灵球有pi的概率被捕获,单独使用第二种精灵球有ui的概率被捕获,同时使用有1-(1-pi)*(1-ui)的概率被捕获.一种精灵球 ...

  7. 2019.03.09 codeforces833B. The Bakery(线段树优化dp)

    传送门 线段树优化dpdpdp入门题. 要求把nnn个数分成kkk段,每段价值为里面不相同的数的个数,求所有段的价值之和最大值.n≤35000,k≤50n\le35000,k\le50n≤35000, ...

  8. GCN代码分析 2019.03.12 22:34:54字数 560阅读 5714 本文主要对GCN源码进行分析。

    GCN代码分析   1 代码结构 . ├── data // 图数据 ├── inits // 初始化的一些公用函数 ├── layers // GCN层的定义 ├── metrics // 评测指标 ...

  9. 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)

    题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...

随机推荐

  1. 如何设置.net控件SplitContainer平均分配

    设置SplitterDistance为宽或者高的一半

  2. React Native: unable to load scripts from assets 'index.android.bundle' on real device

    问题:重新建了一个项目后,运行react-native run-android报: unable to load scripts from assets 'index.android.bundle' ...

  3. CSS 文字太多用省略号表示

    width:150px;/*要显示文字的宽度*/ overflow:hidden; /*超出的部分隐藏起来.*/ white-space:nowrap;/*不显示的地方用省略号...代替*/ text ...

  4. Ubuntu上部署tomcat后无法访问8080端口问题

    在tomacat的bin目录下,修改startup.sh文件,添加信息: #set java environment export JAVA_HOME=/usr/java/jdk1.8.0_111 e ...

  5. python学习Day7 数据类型的转换,字符编码演变历程

    一.数据类型的转换 1.1.1.字符转列表:lst1 = str.split(默认空格,也可依据指定字符分界),若无分界字符,就没法拆分,这时可以直接放进list转成列表 ----> s1 = ...

  6. leetcode268缺失数字

    int missingNumber(int* nums, int numsSize) { ) /; ;i<numsSize;i++){ sum = sum - nums[i]; } return ...

  7. 数据分析三剑客之一numpy

    NumPy系统是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵. 可以用python实现的科学计算包括: 1.一个强大的N维数组对象Array: 2.比较成熟的(广播)函数库: ...

  8. flask中缓存cache导入时引发的错误

    安装 pip install flask-cache 初始化 from flask_cache import Cache cache = Cache(config={ 'CACHE_TYPE': 's ...

  9. mysql学习笔记--数据库内置函数

    一.数字类 1. 生成随机数:rand() a. 随机抽取2位 select * from stuinfo order by rand() limit 2 2. 四舍五入:round(数字) 3. 向 ...

  10. 解决InetAddress.isReachable(timeout)在windows xp始终返回false的bug

    笔者最近在做产品,其中一个环节用到ping测试主机是否在线. 开发环境:Windows 7 64bit+JDK1.8 x64 以下是检测主机是否在线,开发环境中测试通过 public static b ...