Online Judge计蒜客信息学3月提高组模拟赛

Label:记搜,TarJan缩点,树状数组,期望Dp

题解

整个题目由毫无关联的两个问题组合成:

part1

问题:对于每个询问的起点终点,求出起点到终点能够收获的最大矿石价值。

思路:

1.矿石种类不多,且收获价值时只与是否拥有有关,与收集数量无关,可以用状态压缩表示当前收集矿石的状态;

2.由于是单向边且可能形成环,用\(Tarjan\)缩点,然后进行转移。或者直接记忆化dfs/bfs,用\(dp[i][j][sta]\)表示,从\(i\)到\(j\),是否有可能收集到状态为\(sta\)的矿石。最后求一遍最大值即可。

part2

问题:安排执行哪些委托,使得期望获利最大。

思路:

1.整理委托的信息:

对于一份委托\((yi,si,ti,pi,ci,li)\),我们可以根据\((si,ti)\)以及前一个部分的预处理来计算出这份委托的收益(还没减去成本)\(wi\);这份委托的开始时间和结束时间\((yi,yi+li)\),这里简记为\((l,r)\)。这样我们可以用一个结构体表示一份委托{\(l,r,w,c,p\)}。

2.确定转移顺序

毫无疑问先根据开始时间\(li\)排序所有委托。

定义状态\(dp[i]\),表示已经考虑了\(i..q\)的委托,且接受了委托\(i\)时的最大期望获利。接着只用倒序转移即可。对于当前的委托\(i\),我们利用二分查找在\(O(logq)\)的时间内,找到第一个开始时间大于等于当前委托结束时间的委托\(j\)。然后转移方程为:\(dp[i]=max(dp[j...q]+w_i)*(1-p_i)-c_i\),这个很好理解就不解释了,而区间\([j,q]\)的最大值可以用树状数组/线段树维护。

这题就结束了,主要难点是题目变量比较多,只要理清关系分成两个问题求解就好了。

part1的做法比较多,不过由于数据范围小都可行。part2的时间复杂度为\(O(NlogN)\)。

#include<bits/stdc++.h>
using namespace std;
const int N=110,M=210,Q=1e5+10;
int val[1030];
int n,m,k,q,has[N]; struct edge{int to,nxt;}e[M];
int head[N],cnt;
inline void link(int u,int v){
e[++cnt].to=v;e[cnt].nxt=head[u];
head[u]=cnt;
} bool ok[N][N][1030];
void dfs(int s,int x,int sta){
if(ok[s][x][sta])return;
ok[s][x][sta]=1;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;dfs(s,y,sta|has[y]);
}
}
struct Node{
int l,r,w,c;
double p;
}x[Q];
inline bool cmp(Node a,Node b){return a.l<b.l;}
void pre(){
for(register int i=1;i<=n;i++)dfs(i,i,has[i]);
for(register int i=1,u,v;i<=q;i++){
scanf("%d%d%d%lf%d%d",&x[i].l,&u,&v,&x[i].p,&x[i].c,&x[i].r);
x[i].r+=x[i].l;
for(register int o=0;o<(1<<k);o++)if(ok[u][v][o]){
if(val[o]>x[i].w)x[i].w=val[o];
}
}
}
double c[Q];
inline double ask(int x){
double res=0;
while(x<=q){res=max(res,c[x]);x+=x&(-x);}
return res;
}
inline void update(int x,double d){
while(x){c[x]=max(c[x],d);x-=x&(-x);}
}
inline void Dp(){
sort(x+1,x+q+1,cmp);
for(register int i=q;i>=1;i--){
//如果接受i委托,下一个最早能进行的委托是id
int l=i+1,r=q,id=q+1;
while(l<=r){
int mid=l+r>>1;
if(x[i].r<=x[mid].l)r=mid-1,id=mid;
else l=mid+1;
}
double now=(ask(id)+x[i].w)*(1.0-x[i].p)-x[i].c;
update(i,now);
}
printf("%.6f\n",ask(1));
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&q);
for(register int i=1;i<=n;i++){
char s[12];scanf("%s",s);
for(int j=0;j<strlen(s);j++)if(s[j]=='1')has[i]|=1<<j;
}
for(register int i=1;i<=m;i++){
int u,v;scanf("%d%d",&u,&v);
link(u,v);
}
for(register int i=0,w;i<k;i++){
scanf("%d",&w);
for(int j=0;j<(1<<k);j++)if((1<<i)&j)val[j]+=w;
}
pre();
Dp();
}

[计蒜客] 矿石采集【记搜、Tarjan缩点+期望Dp】的更多相关文章

  1. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  2. 计蒜客 作弊揭发者(string的应用)

    鉴于我市拥堵的交通状况,市政交管部门经过听证决定在道路两侧安置自动停车收费系统.当车辆驶入车位,系统会通过配有的摄像头拍摄车辆画面,通过识别车牌上的数字.字母序列识别车牌,通过连接车管所车辆信息数据库 ...

  3. 计蒜客的一道题dfs

    这是我无聊时在计蒜客发现的一道题. 题意: 蒜头君有一天闲来无事和小萌一起玩游戏,游戏的内容是这样的:他们不知道从哪里找到了N根不同长度的木棍, 看谁能猜出这些木棍一共能拼出多少个不同的不等边三角形. ...

  4. 计蒜客模拟赛5 D2T1 成绩统计

    又到了一年一度的新生入学季了,清华和北大的计算机系同学都参加了同一场开学考试(因为两校兄弟情谊深厚嘛,来一场联考还是很正常的). 不幸的是,正当老师要统计大家的成绩时,世界上的所有计算机全部瘫痪了. ...

  5. 计蒜客 等边三角形 dfs

    题目: https://www.jisuanke.com/course/2291/182238 思路: 1.dfs(int a,int b,int c,int index)//a,b,c三条边的边长, ...

  6. 计蒜客 方程的解数 dfs

    题目: https://www.jisuanke.com/course/2291/182237 思路: 来自:https://blog.csdn.net/qq_29980371/article/det ...

  7. 计蒜客 买书 dfs

    题目: https://www.jisuanke.com/course/2291/182236 思路: 递归解决,从第一本书开始,每本书都有两种选择: //index是book里面每本书价格的下标, ...

  8. 计蒜客:Entertainment Box

    Ada, Bertrand and Charles often argue over which TV shows to watch, and to avoid some of their fight ...

  9. 爬虫acm比赛成绩(多页成绩整合在一起、获取复制不了的数据)(hihocoder、计蒜客)

    https://github.com/congmingyige/web-crawler_rank-of-competition-in-JiSuanKe-and-hihocoder 1. 计蒜客(获取复 ...

随机推荐

  1. ETL工具-Kattle:初识kattle

    ETL是EXTRACT(抽取).TRANSFORM(转换).LOAD(加载)的简称,实现数据从多个异构数据源加载到数据库或其他目标地址,是数据仓库建设和维护中的重要一环也是工作量较大的一块.当前知道的 ...

  2. 学习js和jQuery总结

    数据类型的转换:1.字符串必须放在引号内2.字符串的转换有两个标签,string和tostring这两个函数.3.变量必须使用驼峰形式,把一个变量转换成字符串:console.log(isChild. ...

  3. js--判断当前环境是否为iphonex环境

    /** * 判断是否是iphonex */ function getIsIphonex () { var u = navigator.userAgent; var isIOS = !!u.match( ...

  4. vuecli脚手架+vue+vuex实现vue驱动的demo。

    哎呀呀呀,现在大家都要会Vue ||  React,否则感觉跟这个前端的世界脱节了一样. start: vue-cli这个构建工具大大降低了webpack的使用难度,支持热更新,有webpack-de ...

  5. myeclipse CTRL+1功能

    有时候,在myeclipse或者eclipse中自动编译代码有错误,我们把鼠标放在错误一行能够自动显示出问题原因,但是有时显示问题让人有些匪夷所思,不知所云何物. 此时可以使用<ctrl> ...

  6. C#实现程序开机启动

    如何用c#实现开机启动?其实用c#实现程序的开机启动大致有两种方法,就是写入注册表或者采用服务程序,最近一直研究着用C#来操作注册表,下面介绍的方法便是用注册表来实现程序随开机启动(高手就不用看了,嘿 ...

  7. vue.js+element ui Table+spring boot增删改查

    小白初学,不懂的还是太多了,找了好多资料才做出来的先记录一下 1.先用Spring boot创建一个包含了增删改查的项目 2.创建vue.js项目 3.安装Element UI (1)进入项目文件夹下 ...

  8. floyd类型题UVa-10099-The Tourist Guide +Frogger POJ - 2253

    The Tourist Guide Mr. G. works as a tourist guide. His current assignment is to take some tourists f ...

  9. Django2.0+小程序技术打造微信小程序助手✍✍✍

    Django2.0+小程序技术打造微信小程序助手  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题 ...

  10. Team Train Recorder 2.0

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 2019/10/4, solved 4/9, upsolved