先用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. gulp 合格插件评判标准

    官方插件列表:    https://gulpjs.com/plugins/   合格插件的判断标准 1. 不修改内容 如果一个插件一个文件都修改(无论是文案内容,文件路径),那么它就不是一个gulp ...

  2. C#检测应用程序重复启动----函数检测(可以在多用户登录情况下检测)

    上文是在网上找的检测程序重复运行的类,但是感觉不是很好用,而且还使用了API,似乎完全没有必要,于是晚上自己写了一个函数,经过测试,在多用户下仍然可以检测到程序的多次运行.当然,如果程序改了名字还是可 ...

  3. Linux环境安装nginx

    安装需要以下工具: yum -y install gcc gcc-c++ autoconf automake 模块依赖: yum -y install zlib zlib-devel openssl ...

  4. CentOS6安装vsftpd

    练习:完成vsftpd配置 (1) 禁锢系统用户于家目录 [root@node3 ~]# yum -y install vsftpd [root@node3 ~]# vim /etc/vsftpd/v ...

  5. 73个word使用终极技巧

    1.问:Word里边怎样设置每页不同的页眉?如何使不同的章节显示的页眉不同? 答:分节,每节可以设置不同的页眉.文件——页面设置——版式——页眉和页脚——首页不同 2.问:请问Word中怎样让每一章用 ...

  6. 验证DataGridView单元格的值

    private void gridPurchaseOrderDetail_CellValidating(object sender, DataGridViewCellValidatingEventAr ...

  7. HTML5视频直播及H5直播扫盲

    章来源:http://geek.csdn.net/news/detail/95188 分享内容简介: 目前视频直播,尤其是移动端的视频直播已经火到不行了,基本上各大互联网公司都有了自己的直播产品,所以 ...

  8. Ubuntu 下使用 mutt 和 msmtp 发送 Gmail 邮件

    参考:        http://www.cnblogs.com/refrag/archive/2012/11/28/2793533.html         http://www.habadog. ...

  9. EasyUI TreeJson

    1. TreeJson str = GetTreeJsonByTable(dt, "); StringBuilder treeResult = new StringBuilder(); St ...

  10. Py修行路 python基础(六)前期基础整理

    计算机中,有且仅有CPU具有执行权限,能够执行指令的只有CPU! 人在应用程序上输入的文字或文本,叫做明文! 在屏幕上输入或是输出的是字符,计算机保存的是 有字符编码的 二进制数. 变量赋值规则:例如 ...