Description \text{Description} Description

P6054 开门大吉

n n n 位选手去参加节目“开门大吉”。共有 m m m 套题,每套题包含 p p p 个题目,第 i i i 位选手答对第 j j j 套题中第 k k k 道的概率为 f i , j , k f_{i,j,k} fi,j,k​。
若一位选手答对第 i i i 题,会在已得到奖励的基础上,再得到 c i c_i ci​ 元奖励。选手总是从第一道开始,按顺序答题的。
同时,为了防止过多的选手做同一套题,还有 y y y 条形如“第 i i i 位选手的套题编号必须至少比第 j j j 位的大 k k k”的限制。
你需要给每一位选手分配一套题(不同选手可以相同),使得所有人的期望奖励和最小。

Solution \text{Solution} Solution

首先,我们可以简单的算出 i i i 选手选套题 j j j 的期望价值 v i , j v_{i,j} vi,j​。
关键就在于如何表示限制。
建出 n n n 条长度为 m + 1 m+1 m+1 的链,设链上的点为 p 1... n , 1.. m + 1 p_{1...n,1..m+1} p1...n,1..m+1​,连边 ( S , p i , 1 , I N F ) , ( p i , m + 1 , T , I N F ) , ( p i , j , p i , j + 1 , v i , j ) (S,p_{i,1},INF),(p_{i,m+1},T,INF),(p_{i,j},p_{i,j+1},v_{i,j}) (S,pi,1​,INF),(pi,m+1​,T,INF),(pi,j​,pi,j+1​,vi,j​)。断掉 ( p i , j , p i , j + 1 , v i , j ) (p_{i,j},p_{i,j+1},v_{i,j}) (pi,j​,pi,j+1​,vi,j​) 的边即表示令 i i i 选手做 j j j 号题。
这样建图之后限制就容易表示了,设 i i i 选手比 j j j 选手题目编号至少大 k k k,就对于所有合法的下标 x x x,均连边 ( p j , x , p i , x + k , I N F ) (p_{j,x},p_{i,x+k},INF) (pj,x​,pi,x+k​,INF) 即可。

但是这样是无法通过本题的。主流题解都说还需要加上 ( p i , j + 1 , p i , j , I N F ) (p_{i,j+1},p_{i,j},INF) (pi,j+1​,pi,j​,INF) 的边,以实现限制的传递性(或者说保证每条链只断一条边),但我认为这并不是问题的本质,这个连边方法并不是必须的,实践结果也证明了这一点。
我们来看看原来的做法到底为什么出错。
原来的连边方式其实是很健全的,它本身已经有了传递性,如:
红线和绿线限制已经可以进行传递,形成黄色的限制。
那么为什么我们难以通过一些测试点呢?
因为我们的限制没有加全!
题解和我一开始的写法对于限制的加边一般都是写成类似下边的形式:

for(int j=max(1,1-k);j<=m+1&&j+k<=m+1;j++) add(id[y][j],id[x][j+k],inf);

但正确的写法应该是:

for(int j=max(1,1-k);j<=m+1;j++) add(id[y][j],id[x][min(j+k,m+1)],inf);

这两个具象一下就是下面两张图的差别:

注意到,在第一种加法中,后面的两个点没有被限制,成了“法外之地”,这也是为什么加完反向边可以把这个问题修正的原因。
即使可以这么修正,但从问题的本质来看还是不够优美的。因此,建议直接把加限制边的方式修改,而不是进行侧面的修正。

Code \text{Code} Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=2e5+100;
const int M=2e6+100;
const double inf=1e11;
const double eps=1e-6;int n,m,num,y;
int flag;int tot,s,t;
struct node{int to,nxt;double cap;
}p[M<<1];
int fi[N],cur[N],cnt;
inline void addline(int x,int y,double c){p[++cnt]=(node){y,fi[x],c};fi[x]=cnt;
}
inline void add(int x,int y,double c){//printf("%d->%d cap=%.2lf\n\n",x,y,c);addline(x,y,c);addline(y,x,0);
}
int bel[N];
queue<int>que;
int bfs(){fill(bel,bel+1+tot,0);bel[s]=1;que.push(s);while(!que.empty()){int now=que.front();que.pop();for(int i=cur[now]=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(p[i].cap<eps||bel[to]) continue;bel[to]=bel[now]+1;que.push(to);}}return bel[t];
}
double dfs(int x,double lim){if(x==t||lim<eps) return lim;double res(0);for(int &i=cur[x];~i;i=p[i].nxt){int to=p[i].to;if(bel[to]!=bel[x]+1) continue;double add=dfs(to,min(lim,p[i].cap));res+=add;lim-=add;p[i].cap-=add;p[i^1].cap+=add;//printf("x=%d to=%d add=%lf\n",x,to,add);if(lim<eps) break;}if(res<eps) bel[x]=-1;return res;
}
void dinic(){double flow(0),tmp(0);while(bfs()){while((tmp=dfs(s,inf))>eps) flow+=tmp;if(flow>=inf){puts("-1");return;}}printf("%lf\n",flow);return;
}
int id[90][90];
int c[90];
double ans;
double f[90][90][90],pp[90][90][90],val[90][90];
void init(){ans=0;tot=0;for(int i=1;i<=n;i++){for(int j=1;j<=m+1;j++) id[i][j]=++tot;}s=++tot;t=++tot;memset(fi,-1,sizeof(fi));cnt=-1;
}
void calc(){for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){pp[i][j][0]=1;val[i][j]=0;for(int k=1;k<=num;k++) pp[i][j][k]=pp[i][j][k-1]*f[i][j][k];for(int k=1;k<=num;k++){pp[i][j][k]=pp[i][j][k]*(1-f[i][j][k+1]);val[i][j]+=pp[i][j][k]*c[k];}//printf("i=%d j=%d val=%lf\n",i,j,val[i][j]);}}
}void work(){n=read();m=read();num=read();y=read();init();for(int i=1;i<=num;i++) c[i]=read()+c[i-1];for(int j=1;j<=m;j++){for(int i=1;i<=n;i++){for(int k=1;k<=num;k++) scanf("%lf",&f[i][j][k]);}}calc();for(int i=1;i<=n;i++){add(s,id[i][1],inf);add(id[i][m+1],t,inf);for(int j=1;j<=m;j++){add(id[i][j],id[i][j+1],val[i][j]);//add(id[i][j+1],id[i][j],inf);}}for(int i=1;i<=y;i++){int x=read(),y=read(),k=read();for(int j=max(1,1-k);j<=m+1;j++) add(id[y][j],id[x][min(j+k,m+1)],inf);}dinic();return;
}
signed main(){#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);#endifint T=read();while(T--) work();return 0;
}
/*
1
3 2 4 1
10 10 10 20
0.3 0.5 0.7 0.4
0.2 0.6 0.2 0.2
0.7 0.1 0.8 0.2
0.5 0.5 0.5 0.5
0.2 0.5 0.3 0.6
0.3 0.5 0.4 0.1
2 3 1
*/

洛谷P6054:开门大吉相关推荐

  1. 教你如何更改在洛谷里的运势

    如何更改你在洛谷里的运势 你会不会经常满怀期待的打开洛谷 却发现今天的运势是凶 多么令人伤心啊qwq 但是,今天我来教你,如何让运势瞬间变成大吉. 第一步:打开洛谷 然后-没了 第二步:右击写着&qu ...

  2. 洛谷刷题C语言:【Mc生存】经验值、开灯、乘积最大3、三角函数、电梯里的爱情

    记录洛谷刷题QAQ 一.[Mc生存]经验值 题目背景 初一福利第2弹... 题目描述 话说 clearman 在 MC 世界开了个祥艺奶牛场,用熔浆.TNT 等丧心病狂的折磨牛,获取牛肉.牛奶等刷经验 ...

  3. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  4. 洛谷 P1142 轰炸

    洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...

  5. 洛谷 P1387 最大正方形

    P1387 最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=10 ...

  6. 洛谷P2763 试题库问题

    题目:https://www.luogu.org/problemnew/show/P2763 题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性. ...

  7. 动态规划——洛谷_P1057传球游戏

    题目: 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏.游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球, ...

  8. 洛谷P1417 烹调方案

    洛谷P1417 烹调方案 如果是一般的01背包的话 选的先后是没关系的 但是这题选的先后是有关系的,因为他的价值是随着时间而变化的, 而你的01背包是做不到先选2再选1的 那么我们就跟国王游戏一样 用 ...

  9. 记忆优化搜索(简单题)(洛谷P3183 [HAOI2016]食物链 )( P5635 【CSGRound1】天下第一 )

    昨天做了蓝桥杯的时候,发现自己对于记忆优化搜索甚是不熟悉,所以今天随便找了几个基础题做做,顺便写下两片题解,顺便用了一下devc++敲的代码,发现没有代码补全真的可以说是灰常难受了... 洛谷P318 ...

最新文章

  1. Cloneable接口和循环冗余校验算法
  2. CenterNet-TensorRT 3D Detection
  3. glVertexPointer
  4. 七天入门linux,RHCE认证学习笔记-第七天
  5. 固定div的位置——不随窗口大小改变为改变位置
  6. STM32下载库资料
  7. php中finally不能用,php-什么时候以及为什么`finally`有用?
  8. shell实现简单的进程监控脚本
  9. spring 基于注解的控制器配置
  10. ios34---GDC,dispatch_once
  11. 查看文件详细信息linux,linux命令stat,查看文件详细信息
  12. ubuntu 电源按钮操作_电源菜单和按笔记本电脑电源按钮时缺少休眠
  13. 《Android开发从零开始》——31.模拟Http请求
  14. Oracle listagg去重distinct三种方法总结
  15. 哈工大车万翔教授:NLPer的核心竞争力是什么?
  16. 富士胶片展示透明投影膜、CMF表面装饰材料及HydroAg+抗菌技术
  17. Private VLAN 与Switchport Protected
  18. 用记事本编写小游戏_一款适合你的记事本——提高你工作的效率!
  19. 用大家的力量来总结一个目录(众人拾柴火焰高)
  20. HTML页面上传图片直接预览

热门文章

  1. clientX,screenX,pageX,offsetX的区别
  2. 太阳能、热源给单锂电池充电CN3131
  3. 碧玉刀服务器维护,有关碧玉刀任务的
  4. 教你如何用纯CSS代码实现垂直居中
  5. 小程序 wx.showToast 一闪而过的解决办法
  6. 最新web前端面试题大全
  7. AI 科学家带你快速 Get 人工智能最热技术
  8. Java的历史和技术体系
  9. SnapHelper解析
  10. MyCollector - 快捷采集器 :让你更方便的记录快乐