bzoj1003 trans DP
最初的印象是网络流之类的东西,但好像不是。
想了一下,没什么思路,就网上看了一下,有人说是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的更多相关文章
- BZOJ 1003: [ZJOI2006]物流运输trans DP+最短路
Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...
- BZOJ3163&Codevs1886: [Heoi2013]Eden的新背包问题[分治优化dp]
3163: [Heoi2013]Eden的新背包问题 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 428 Solved: 277[Submit][ ...
- P3193 [HNOI2008]GT考试(KMP+矩阵乘法加速dp)
P3193 [HNOI2008]GT考试 思路: 设\(dp(i,j)\)为\(N\)位数从高到低第\(i\)位时,不吉利数字在第\(j\)位时的情况总数,那么转移方程就为: \[dp(i,j)=dp ...
- bzoj题解汇总(1001-1016)
bzoj1001: 平面图网络流. 注意只有一行或者一列的情况. bzoj1002: 待定系数法求解递归式.或者用MatrixTree+行列式直接推导. 然后来个高精度. bzoj1003: dp+最 ...
- BZOJ ac100题存档
不知不觉AC100题了,放眼望去好像都是水题.在这里就做一个存档吧(特别感谢各位大神尤其是云神http://hi.baidu.com/greencloud和丽洁姐http://wjmzbmr.com/ ...
- 解题:WC 2018 州区划分
题面 WC之前写的,补一补,但是基本就是学新知识了 首先可以枚举子集$3^n$转移,优化是额外记录每个集合选取的个数,然后按照选取个数从小到大转移.转移的时候先FWT成“点值”转移完了IFWT回去乘逆 ...
- poj1722 SUBTRACT
应该是基础的dp练手题 线性dp最主要的就是关于阶段的划分,这个题中我没想到的一点就是开状态的时候使用了前i个数能合成的数来记录 我自己的想法就是类似于区间dp这样的记录方法,这种方法确实开了很多冗余 ...
- BZOJ 1~10 精简题解
从这星期起,我开始了怒刷BZOJ的旅程.这几天刷了10道题(由于"档期"的原因,所以有几道题没打完-..捂脸--..) 精简题解: 1000 A+B Problem --.. [B ...
- BZOJ-1003 物流运输trans SPFA+DP
傻逼错误耗我1h,没给全范围坑我1A.... 1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec Memory Limit: 162 MB Submit: 529 ...
随机推荐
- eclipse运行Android项目出现“The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ”
重启eclipse之后仍然出现同样错误,此时可以尝试一下方法: cmd打开命令窗口: 之后重启eclipse,基本可以解决问题!
- bzoj 2303 并查集
首先如果没有限制的话,我们可以直接求出答案,假设对于n*m的矩阵,我们最上方一行和左方的一列随意确定,那么首先这写确定的状态肯定是不会不合法的,因为我们可以调整剩下的01状态来使得这一行一列的状态合法 ...
- JavaScript 使用闭包保护变量 防止污染
使用JavaScript编写插件或团队协作时,可使用闭包来解决此类以下两个问题: 1.定义过多全局变量,可能会造成全局变量命名冲突: 2.在插件内定义变量,需要保护该变量不被轻易修改: 优点:可以把局 ...
- windows7下安装配置phonegap3.0 (cordavo)开发环境 (涉及android sdk配置)
之前在mac上安装调试过phonegap,现在公司用的是windows7,所以不得不再进行一次windows下的配置工作,顺便也写下来了 主要麻烦的地方是要在win7下添加好几个环境变量,这一块地方特 ...
- Friends and Berries URAL - 2067 (计算三点共线和计算的时候的注意点)
题目链接:https://cn.vjudge.net/problem/URAL-2067 具体思路:判断三点共线就可以了,只有一对点能满足,如果一对就没有那就没有满足的. 在计算的时候,要注意,如果是 ...
- 微信access_token和refresh_token保存于redis
简介 通常理解的access_token和refresh_token access_token是用来对客户端进行认证的,类似与密码,有一定的有效期.当过期后可使用refresh_token重新获取一个 ...
- 在Ubuntu上安装Redis MySQL MongoDB memcached Nginx
1.安装Redis sudo apt-get install redis-server 2.安装MySQL sudo apt-get install mysql-server 3.安装MongoDB ...
- 让R与Python共舞
转载:http://ices01.sinaapp.com/?p=129 R(又称R语言)是一款开源的跨平台的数值统计和数值图形化展现 工具.通俗点说,R是用来做统计和画图的.R拥有自己的脚本 ...
- Codeforces 375D - Tree and Queries(dfs序+莫队)
题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...
- Effective STL 笔记: Item 6--Be alert for C++'s most vexing parse
假设有个文件里面记录的一系列的 int 值,现在我们想把这些数值存到一个 List 里面,结合 Item 5, 我们可能会写出下面的代码: ifstream dataFile("ints.d ...