NOIP 2016 换教室
时间:2019-09-15
本文章向大家介绍NOIP 2016 换教室,主要包括NOIP 2016 换教室使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
-1 感谢
参考题解(逃感谢zzy学长讲解的期望dp。
0 预知识
期望和dp
1 设计状态
我们很容易想到用
\[f_{i,j}\]
表示前\(i\)次课申请换了\(j\)次教室的最短路程。但这样是没办法转移的。
这时就需要一个想法:设状态
\[f_{i,j,0/1}\]
表示前\(i\)次课申请换了\(j\)次教室的最短路程,并且第\(i-1\)次课有(1)没有(0)申请换教室。
2 转移
这样的话就好转移了。我们设
\[C1=c_{i-1},C2=d_{i-1},C3=c_i,C4=d_i\]
确实是ViXbob题解上的,别喷我啊qwq
那方程就是
其实想好了状态之后方程就一目了然了。具体解释见代码。其实自己手玩一下直接就出来了嘛
3 代码
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf = 5e8;
const int N = 2001;
const int V = 301;
int n,m,v,e;
int c[N],d[N];
int dis[V][V];
double k[N];
double f[N][N][2];
double ans=inf;
inline void readx(int &x)
{
x=0; int s=-1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') s=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
x*=s;
}
inline void Init()
{
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=1;i<=v;++i) for(int j=1;j<=v;++j) dis[i][j]=inf;
for(int i=1;i<=n;++i) scanf("%d",&c[i]);
for(int i=1;i<=n;++i) scanf("%d",&d[i]);
for(int i=1;i<=n;++i) scanf("%lf",&k[i]);
for(int i=1;i<=e;++i)
{int _a,_b,_c;scanf("%d%d%d",&_a,&_b,&_c);dis[_a][_b]=dis[_b][_a]=min(dis[_a][_b],_c);}
//这里千万记得判重边,这个重边贼恶心人!!!
for(int i=1;i<=v;++i) dis[i][i]=0;
for(int k=1;k<=v;++k)
for(int i=1;i<=v;++i)
for(int j=1;j<=v;++j)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=1;i<=n;++i)
for(int j=0;j<=m;++j)
f[i][j][0]=f[i][j][1]=inf;
f[1][0][0]=f[1][1][1]=0;
}
//理解一下应该能看懂
inline void DP()
{
for(int i=2;i<=n;++i)
{
int mi=min(m,i);
f[i][0][0]=f[i-1][0][0]+dis[c[i-1]][c[i]];
for(int j=1;j<=mi;++j)
{
int C1=c[i-1],C2=d[i-1],C3=c[i],C4=d[i];
f[i][j][0]=min(
f[i-1][j][0]+dis[C1][C3],//C1->C3
f[i-1][j][1]+dis[C1][C3]*(1-k[i-1])+dis[C2][C3]*k[i-1]//C1->C3 & C2->C3
);
f[i][j][1]=min(
f[i-1][j-1][0]+dis[C1][C3]*(1-k[i])+dis[C1][C4]*k[i],//C1->C3 & C1->C4
f[i-1][j-1][1]+
dis[C1][C3]*(1-k[i-1])*(1-k[i])//C1->C3
+dis[C1][C4]*(1-k[i-1])*k[i]//C1->C4
+dis[C2][C3]*k[i-1]*(1-k[i])//C2->C3
+dis[C2][C4]*k[i-1]*k[i]//C2-C4
);
//形象直观QAQ
}
}
}
//懒得打方程了(逃
int main()
{
Init();
DP();
for(int i=0;i<=m;++i) ans=min(ans,min(f[n][i][0],f[n][i][1]));
printf("%.2lf\n",ans);
return 0;
}
4 后记
判重边!
判重边!!
判重边!!!
再忘判重边我就女装!!!
原文地址:https://www.cnblogs.com/oierwyh/p/11522340.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 用回溯算法求解数独问题
- bug 回忆录(四)
- 新手入门系列之-React / Vue 应用持续集成Docker 化
- Android 获取进程名函数,如何优化到极致?
- R语言做K均值聚类的一个简单小例子
- 如何自动化Salesforce应用程序
- 2万字带你学习Qos原理,还有6个实验案例,建议一定要收藏!
- 最全总结 | 聊聊 Python 数据处理全家桶(MongoDB 篇)
- R函数
- unstack函数应用——生成单细胞marker基因表格
- 手把手教你使用Python打造一个智能搜索淘宝商品,生成操作日志的系统
- leetcode树之将有序数组转换为二叉搜索树
- Mysql必知必会!
- 【一天一大 lee】路径总和 II (难度:中等) - Day20200926
- 【一天一大 lee】从中序与后序遍历序列构造二叉树 (难度:中等)-Day20200925