先用Floyed做亮点之间的最短路,设计dp,记dp[i][j][0]为到第i节课,换了j次课,当前有没有换课达到的期望耗费体力最小值

方程(太长了还是看代码吧):
dp[i][j][0]<-dp[i - 1][j][0]
dp[i][j][0]<-dp[i - 1][j][1]
dp[i][j][1]<-dp[i - 1][j - 1][0]
dp[i][j][1]<-dp[i - 1][j - 1][1]

~~感觉跟没说一样~~

初值: inf, dp[1][0][0] = dp[1][1][1] = 0
在每一次枚举m转移之前有 dp[i][0][0] = dp[i - 1][0][0] + dis[c[i - 1]][c[i]]

转移顺序:……显然从小到大枚举转移

【锅】
一开始没有想清楚状态之间的关系, 只设计了两维dp,于是,这个样例完美地救了我,下次在搞之前还是要手算一遍a

Code:

#include <cstdio>

using namespace std;

typedef double db;

const int N = ;
const int P = ;
const int inf = << ; int n, m, pNum, eNum, c[N], d[N], dis[P][P];
db k[N], dp[N][N][]; template <typename T>
inline T min(T x, T y) {
return x > y ? y : x;
} inline void floyed() {
for(int l = ; l <= pNum; l++)
for(int i = ; i <= pNum; i++)
for(int j = ; j <= pNum; j++)
dis[i][j] = min(dis[i][j], dis[i][l] + dis[l][j]);
} int main() {
scanf("%d%d%d%d", &n, &m, &pNum, &eNum);
for(int i = ; i <= n; i++)
scanf("%d", &c[i]);
for(int i = ; i <= n; i++)
scanf("%d", &d[i]);
for(int i = ; i <= n; i++)
scanf("%lf", &k[i]); for(int i = ; i <= pNum; i++)
for(int j = ; j <= pNum; j++)
if(i != j) dis[i][j] = inf;
for(int x, y, v, i = ; i <= eNum; i++) {
scanf("%d%d%d", &x, &y, &v);
dis[x][y] = min(dis[x][y], v);
dis[y][x] = dis[x][y];
}
floyed(); /* for(int i = 2; i <= n + 1; i++)
for(int j = 1; j <= m; j++)
dp[i][j] = (db)inf;
for(int i = 1; i <= n + 1; i++)
dp[i][0] = dp[i - 1][0] + (db) dis[c[i - 1]][c[i]];
db ans = dp[n + 1][0];
printf("%.2f ", dp[n + 1][0]);
for(int i = 2; i <= n + 1; i++)
for(int j = 1; j <= m; j++) {
dp[i][j] = min(dp[i][j], dp[i - 1][j] + (db)dis[c[i - 1]][c[i]]); db t = dp[i - 2][j - 1];
t += (db) k[i] * (dis[c[i - 2]][d[i - 1]] + dis[d[i - 1]][c[i]]);
t += (db) (1 - k[i]) * (dis[c[i - 2]][c[i - 1]] + dis[c[i - 1]][c[i]]);
dp[i][j] = min(dp[i][j], t); if(i == n + 1) ans = min(dp[i][j], ans);
}
printf("%.2f %.2f %.2f ", dp[1][1], dp[2][1], dp[3][2]);
ans = min(ans, dp[n + 1][0]); */ for(int i = ; i<= n; i++)
for(int j = ; j <= m; j++)
for(int l = ; l <= ; l++)
dp[i][j][l] = (db) inf;
dp[][][] = dp[][][] = ; db ans = (db) inf;
for(int i = ; i <= n; i++) {
dp[i][][] = dp[i - ][][] + dis[c[i - ]][c[i]];
for(int j = ; j <= m; j++) { db p[];
p[] = k[i - ], p[] = k[i], p[] = - k[i - ], p[] = - k[i]; int t[];
t[] = c[i - ], t[] = d[i - ], t[] = c[i], t[] = d[i]; dp[i][j][] = min(dp[i][j][], dp[i - ][j][] + dis[t[]][t[]]);
dp[i][j][] = min(dp[i][j][], dp[i - ][j][] + p[] * dis[t[]][t[]] + p[] * dis[t[]][t[]]); dp[i][j][] = min(dp[i][j][], dp[i - ][j - ][] + p[] * dis[t[]][t[]] + p[] * dis[t[]][t[]]);
dp[i][j][] = min(dp[i][j][], dp[i - ][j - ][] + p[] * p[] * dis[t[]][t[]] + p[] * p[] * dis[t[]][t[]] + p[] * p[] * dis[t[]][t[]] + p[] * p[] * dis[t[]][t[]]);
if(i == n) ans = min(ans, min(dp[i][j][], dp[i][j][]));
}
}
ans = min(ans, dp[n][][]); printf("%.2f", ans);
return ;
}

Luogu 1580 [NOIP2016] 换教室的更多相关文章

  1. [NOIP2016]换教室 D1 T3 Floyed+期望DP

    [NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...

  2. BZOJ 4720 [Noip2016]换教室

    4720: [Noip2016]换教室 Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i( ...

  3. 【BZOJ】4720: [Noip2016]换教室

    4720: [Noip2016]换教室 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1690  Solved: 979[Submit][Status ...

  4. bzoj4720: [Noip2016]换教室(期望dp)

    4720: [Noip2016]换教室 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1294  Solved: 698[Submit][Status ...

  5. [Luogu 1850] noip16 换教室

    [Luogu 1850] noip16 换教室 好久没有更博客了,先唠嗑一会,花了两天的空闲时间大致做完了昨年的noip真题 虽然在经过思考大部分题目都可出解(天天爱跑步除外),但是并不知道考试时候造 ...

  6. [NOIP2016]换教室 题解(奇怪的三种状态)

    2558. [NOIP2016]换教室 [题目描述] 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1< ...

  7. [NOIP2016]换教室(概率期望$DP$)

    其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...

  8. 【bzoj4720】[NOIP2016]换教室

    题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的课程同时在不同的 ...

  9. [NOIp2016] 换教室

    题目类型:期望\(DP\) 传送门:>Here< 题意:现有\(N\)个时间段,每个时间段上一节课.如果不申请换教室,那么时间段\(i\)必须去教室\(c[i]\)上课,如果申请换课成功, ...

随机推荐

  1. Dijkstra算法(带路径模板)

    个人心得:Dijkstra算法是贪心思想的一种延伸,注意路径pre,pre数组表示此时最短路径中的前一个顶点.每次更新到目的点时更新: 从源点出发,更新路径,然后找出此时最短的点,然后以这个点为头,看 ...

  2. [C/C++]宽字符与控制台程序

    转自:http://www.cnblogs.com/zplutor/archive/2010/11/27/1889227.html 在我刚开始学C/C++的时候,字符类型使用的都是char.接触Win ...

  3. XML的应用 ---- 从一个范例看xml数据、xsd验证、xslt样式

    从一个范例看XML的应用 引言 如果你已经看了Asp.Net Ajax的两种基本开发模式 这篇文章,你可能很快会发现这样一个问题:在那篇文章的方式2中,客户端仅仅是发送了页面上一个文本框的内容到服务端 ...

  4. VBA程序的调试

    VBA程序的调试:设置断点.单步跟踪.设置监视窗 Acces的VBE编程环境提供了完整的一套调试工具和调试方法.熟练掌握好这些调试工具和调试方法的使用,可以快速.准确地找到问题所在,不断修改,加以完善 ...

  5. utf_8 和 GBK 不搭出现乱码(转)

    今天调数据的时候发现调出来的一直是乱码,用了各种方法都未解决,简单的调数据用了好长时间,最后突然发现了一个问题 页面的 <meta http-equiv="Content-Type&q ...

  6. IaaS vs PaaS vs SaaS

    在云计算的早期阶段,企业面临的最大问题是他们是否应该使用公共云服务.如今,几乎所有的组织都在采用一些公共云服务.更重要的问题是企业应该使用哪种云服务:基础设施即服务(IaaS),平台即服务(PaaS) ...

  7. bootstrap 设置表格固定宽度 内容换行

    在项目中开发的时候用的bootstrap,但是有些表格的内容 会显示的很长 那么我第一时间想到的就是 修改td或者th的width,但是我设置了 之后不起作用 于是百度找到了解决方法: 学习源头: h ...

  8. GitFlow在命令行的使用

    gitflow安装 在命令行直接使用yum安装 yum install gitflow 如果本地的yum源中不存在gitflow,可以尝试添加EPEL源 CentOS6.5: # 下载 wget ht ...

  9. python开发模块基础:re正则

    一,re模块的用法 #findall #直接返回一个列表 #正常的正则表达式 #但是只会把分组里的显示出来#search #返回一个对象 .group()#match #返回一个对象 .group() ...

  10. Java开发需要注意的流程

    将一些需要变动的配置写在属性文件中 比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置.那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无阻地运行,但是一旦部署在PROD ...