最初的印象是网络流之类的东西,但好像不是。

想了一下,没什么思路,就网上看了一下,有人说是DP,然后就自己想DP的做法,最开始想的状态是:dp[n][s] 第n天走s这条路,前n天最小的代价,但发现路径不好表示,并且m=20时s最大就是10^6级别了,所以放弃了这个状态。

打开题解,发现题解的状态不需要记录s,即dp[n]表示前n天最小的代价和,然后用一个辅助数组mdis[i][j]表示从第i天到第j天所有限制共同作用下的图的最短路。转移:

  dp[i] = min( mdis[1][i]*i, dp[j]+mdis[j+1][i]*(i-j)+K | j in [1,i) }

的确很好,也很自然(对于一个最优解,必定是由一些“路径改变点”组成,而两个“路径改变点"之间走的一定是满足该区间限制下的最短路,我们每次只需要枚举最后一个路径改变点,就可以转移了)。有点像一个多决策问题(对于每一天,决策是改变或不改变路径)。

 /**************************************************************
Problem: 1003
User: idy002
Language: C++
Result: Accepted
Time:28 ms
Memory:860 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#define maxn 110
#define maxm 25
#define inf 0x3f3f3f3f
using namespace std; int n, m, e, K; vector<int> g[maxm], wght[maxm];
bool gave[maxm][maxn];
bool cave[maxm]; int mdis[maxn][maxn];
int dis[maxm];
bool done[maxm];
int dp[maxn]; void input() {
scanf( "%d%d%d%d", &n, &m, &K, &e );
for( int i=,u,v,w; i<=e; i++ ) {
scanf( "%d%d%d", &u, &v, &w );
g[u].push_back(v);
g[v].push_back(u);
wght[u].push_back(w);
wght[v].push_back(w);
}
memset( gave, , sizeof(gave) );
int d;
scanf( "%d", &d );
for( int i=,u,a,b; i<=d; i++ ) {
scanf( "%d%d%d", &u, &a, &b );
for( int i=a; i<=b; i++ )
gave[u][i] = false;
}
} struct Stat {
int u, dis;
Stat( int u, int dis ):u(u),dis(dis){}
bool operator<( const Stat & b ) const {
return dis>b.dis;
}
};
int dijstra( int s, int d ) {
priority_queue<Stat> hp;
memset( done, false, sizeof(done) );
memset( dis, 0x3f, sizeof(dis) );
dis[s] = ;
hp.push( Stat(s,) );
while( !hp.empty() ) {
int u = hp.top().u;
hp.pop();
if( done[u] ) continue;
done[u] = true;
if( u==d ) return dis[d];
for( int t=; t<g[u].size(); t++ ) {
int v = g[u][t];
int w = wght[u][t];
if( !cave[v] ) continue;
if( dis[v]>dis[u]+w ) {
dis[v]=dis[u]+w;
hp.push( Stat(v,dis[v]) );
}
}
}
return inf;
}
void prep() {
memset( mdis, 0x3f, sizeof(mdis) );
for( int i=; i<=n; i++ ) {
memset( cave, , sizeof(cave) );
for( int j=i; j<=n; j++ ) {
for( int u=; u<=m; u++ )
cave[u] &= gave[u][j];
mdis[i][j] = dijstra(,m);
}
}
}
void work() {
for( int i=; i<=n; i++ ) {
if( mdis[][i]!=inf )
dp[i] = mdis[][i]*i;
else dp[i]=inf;
for( int j=; j<i; j++ )
if( mdis[j+][i]!=inf )
dp[i] = min( dp[i], dp[j]+mdis[j+][i]*(i-j)+K );
}
printf( "%d\n", dp[n] );
}
int main() {
input();
prep();
work();
}

bzoj1003 trans DP的更多相关文章

  1. BZOJ 1003: [ZJOI2006]物流运输trans DP+最短路

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  2. BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]

    3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 428  Solved: 277[Submit][ ...

  3. P3193 [HNOI2008]GT考试(KMP+矩阵乘法加速dp)

    P3193 [HNOI2008]GT考试 思路: 设\(dp(i,j)\)为\(N\)位数从高到低第\(i\)位时,不吉利数字在第\(j\)位时的情况总数,那么转移方程就为: \[dp(i,j)=dp ...

  4. bzoj题解汇总(1001-1016)

    bzoj1001: 平面图网络流. 注意只有一行或者一列的情况. bzoj1002: 待定系数法求解递归式.或者用MatrixTree+行列式直接推导. 然后来个高精度. bzoj1003: dp+最 ...

  5. BZOJ ac100题存档

    不知不觉AC100题了,放眼望去好像都是水题.在这里就做一个存档吧(特别感谢各位大神尤其是云神http://hi.baidu.com/greencloud和丽洁姐http://wjmzbmr.com/ ...

  6. 解题:WC 2018 州区划分

    题面 WC之前写的,补一补,但是基本就是学新知识了 首先可以枚举子集$3^n$转移,优化是额外记录每个集合选取的个数,然后按照选取个数从小到大转移.转移的时候先FWT成“点值”转移完了IFWT回去乘逆 ...

  7. poj1722 SUBTRACT

    应该是基础的dp练手题 线性dp最主要的就是关于阶段的划分,这个题中我没想到的一点就是开状态的时候使用了前i个数能合成的数来记录 我自己的想法就是类似于区间dp这样的记录方法,这种方法确实开了很多冗余 ...

  8. BZOJ 1~10 精简题解

    从这星期起,我开始了怒刷BZOJ的旅程.这几天刷了10道题(由于"档期"的原因,所以有几道题没打完-..捂脸--..) 精简题解: 1000 A+B Problem --.. [B ...

  9. BZOJ-1003 物流运输trans SPFA+DP

    傻逼错误耗我1h,没给全范围坑我1A.... 1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec Memory Limit: 162 MB Submit: 529 ...

随机推荐

  1. 通过cordova将vue项目打包为webapp

    准备工作:需要之前配置好vue-cli脚架构,安装好cordova环境.下面开始对vue.js项目进行打包,打包环境为Android. 可以看下我的github:https://github.com/ ...

  2. 【Git】git clone与git pull区别

    从字面意思也可以理解,都是往下拉代码,git clone是克隆,git pull 是拉.但是,也有区别: 从远程服务器克隆一个一模一样的版本库到本地,复制的是整个版本库,叫做clone.(clone是 ...

  3. flask插件系列之flask_cors跨域请求

    前后端分离在开发调试阶段本地的flask测试服务器需要允许跨域访问,简单解决办法有二: 使用flask_cors包 安装 pip install flask_cors 初始化的时候加载配置,这样就可以 ...

  4. 【swupdate文档 五】从可信的来源更新镜像

    从可信的来源更新镜像 现在越来越重要的是,设备不仅要能安全地进行更新操作, 而且要能够验证发送的图像是否来自一个已知的源, 并且没有嵌入恶意软件. 为了实现这个目标,SWUpdate必须验证传入的镜像 ...

  5. sshpass-免交互SSH登录工具

    sshpass用于自动向命令行提供密码,适用于ssh,scp,rsync,pssh,pscp等ssh系列的命令和工具 #安装sshpass yum install sshpass -y #注:当第一次 ...

  6. php cache类代码(php数据缓存类)

    如果访问量大的话会给数据库造成很大的负担,所以对于变化不经常的内容要做好php 数据cache(缓存)是十分必要的,我做了一个简单的php“文件缓存”的类,希望对大家有所帮助. 思路是这样的: 对于一 ...

  7. inux命令英文缩写的含义(方便记忆) 2

    linux常用命令的英文单词缩写 命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户rpm:redhat packa ...

  8. Effective C++笔记(六):继承与面向对象设计

    参考:http://www.cnblogs.com/ronny/p/3756494.html 条款32:确定你的public继承塑模出is-a关系 “public继承”意味着is-a.适用于base ...

  9. 深度学习方法(十二):卷积神经网络结构变化——Spatial Transformer Networks

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.机器学习技术感兴趣的同学加入. 今天具体介绍一个Google ...

  10. Effective STL 阅读笔记: Item 3: Make copying cheap and correct for objects in containers

    容器 (Containers) 用来存储对象 (Objects), 但是被存储的对象却并非原原本本是你给他的那一个, 而是你指定对象的一个拷贝.而后续对该容器内存储对象的操作,大多也是基于拷贝的. 拷 ...