[CSP-S模拟测试]:旅行计划(分块+DP)
题目传送门(内部题83)
输入格式
第一行两个整数$n,m$
接下来$m$行,每行三个整数,$u,v,w$,表示从$u$到$v$有一条权值为$w$的边
接下来一行有一个整数$q$,表示$q$天
接下来$q$行,每行三个整数,$s_i,t_i,k_i$,表示从$s_i$到$t_i$至少经过$k_i$条边
输出格式
一共$q$行,每行一个整数,表示在第$i$天中的最短距离,如果没有符合要求的答案,输出$-1$。
样例
样例输入:
3 3
1 2 1
2 3 10
3 1 100
3
1 1 1
1 2 1
1 3 1
样例输出:
111
1
11
数据范围与提示
对于$30\%$的数据,$k_i\leqslant 50$
对于另外$30\%$的数据,$q\leqslant 50$
对于$100\%$的数据,$n\leqslant 50,m\leqslant 10,000,wi\leqslant 10,000,q\leqslant 100,000,ki\leqslant 10,000$
题解
$DP$和分块可能很难接合在一起,但是他们做到了。
不妨设$f[i][j][k]$表示从$i$到$j$恰好走$k$步的方案数,稍做修改就能做到至少走$k$步的方案数。
再设$p[i][j]$表示从$i$到$j$恰好走$100$步的方案数,这个数组也就是这道题的关键,将其分块了。
最后设$g[i][j][k]$表示从$i$到$j$恰好走$100\times k$的方案数即可。
最后答案就是$\min\limits_{i=1}^n(g[s][i][k/100]+f[i][t][k\%100])$。
时间复杂度:$\Theta(100\times n+q\times n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n,m,q;
int d[51][51],p[51][51],g[51][51][200],f[51][51][200];
int main()
{
memset(d,0x3f,sizeof(d));
memset(g,0x3f,sizeof(g));
memset(f,0x3f,sizeof(f));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
d[u][v]=min(d[u][v],w);
}
for(int i=1;i<=n;i++)
{
f[i][i][0]=0;
for(int j=0;j<n+100;j++)
for(int k=1;k<=n;k++)
for(int l=1;l<=n;l++)
f[i][l][j+1]=min(f[i][l][j+1],f[i][k][j]+d[k][l]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
p[i][j]=f[i][j][100];
for(int k=n+100;~k;k--)
f[i][j][k]=min(f[i][j][k],f[i][j][k+1]);
}
for(int i=1;i<=n;i++)
{
g[i][i][0]=0;
for(int j=0;j<100;j++)
for(int k=1;k<=n;k++)
for(int l=1;l<=n;l++)
g[i][l][j+1]=min(g[i][l][j+1],g[i][k][j]+p[k][l]);
}
scanf("%d",&q);
while(q--)
{
int s,t,k,ans=0x3f3f3f3f;
scanf("%d%d%d",&s,&t,&k);
for(int i=1;i<=n;i++)ans=min(ans,f[i][t][k%100]+g[s][i][k/100]);
if(ans==0x3f3f3f3f)puts("-1");
else printf("%d\n",ans);
}
return 0;
}
rp++
[CSP-S模拟测试]:旅行计划(分块+DP)的更多相关文章
- [CSP-S模拟测试]:Market(背包DP)
题目描述 在比特镇一共有$n$家商店,编号依次为$1$到$n$.每家商店只会卖一种物品,其中第$i$家商店的物品单价为$c_i$,价值为$v_i$,且该商店开张的时间为$t_i$. $Byteasar ...
- [CSP-S模拟测试]:B(期望DP)
题目传送门(内部题151) 输入格式 第一行一个整数$N$. 第二行$N$个整数,第$i$个为$a_i$. 输出格式 一行一个整数,表示答案.为避免精度误差,答案对$323232323$取模. 即设答 ...
- [CSP-S模拟测试]:密码(数位DP+库默尔定理)
题目描述 为了揭穿$SERN$的阴谋,$Itaru$黑进了$SERN$的网络系统.然而,想要完全控制$SERN$,还需要知道管理员密码.$Itaru$从截获的信息中发现,$SERN$的管理员密码是两个 ...
- [CSP-S模拟测试]:硬币(博弈论+DP+拓展域并查集)
题目传送门(内部题135) 输入格式 第一行包含一个整数$T$,表示数据组数. 对于每组数据,第一行两个整数$h,w$,表示棋盘大小. 接下来$h$行,每行一个长度为$w$的字符串,每个位置由为$o, ...
- [CSP-S模拟测试]:军训队列(DP+乱搞)
题目描述 有$n$名学生参加军训,军训的一大重要内容就是走队列,而一个队列的不规整程度是该队中最高的学生的身高与最矮的学生的身高差值的平方.现在要将$n$名参加军训的学生重新分成$k$个队列,每个队列 ...
- [CSP-S模拟测试]:优化(贪心+DP)
题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连 ...
- [CSP-S模拟测试]:玩具(概率DP)
题目描述 这个故事发生在很久以前,在$IcePrincess\text{_}1968$和$IcePrince\text{_}1968$都还在上幼儿园的时候. $IcePrince\text{_}196 ...
- [CSP-S模拟测试]:超级树(DP)
题目传送门(内部题5) 输入格式 一行两个整数$k$.$mod$,意义见上. 输出格式 一行一个整数,代表答案. 样例 样例输入1: 2 100 样例输出1: 样例输入2: 3 1000 样例输出2: ...
- [CSP-S模拟测试]:Park(树上DP)
题目描述 公园里有$n$个雕像,有$n-1$条道路分别连接其中两个雕像,任意两个雕像可以直接或间接相连.现在每个景点$i$聚集着$P_i$只鸽子,旅行家手里有$v$数量的面包屑. 一旦旅行家在雕像$i ...
随机推荐
- python一行代码打印Love心形
用Python画一颗特别的爱心,送给那个特别的她,给她一份浪漫的惊喜吧 print('\n'.join([''.join([('Love'[(x-y) % len('Love')] if ((x*0. ...
- 邀请好友注册页面光标点到输入框后,输入框会先灰一下。只有ios存在
输入框会先灰一下.只有ios存在 用这一行代码可以解决问题: -webkit-tap-highlight-color:transparent;
- .net core 2.2.0 SOAP踩坑
首先确认下面几个程序集是最新版本: <PackageReference Include="System.ServiceModel.Http" Version="4. ...
- luogu P4548 [CTSC2006]歌唱王国
传送门 这题\(\mathrm{YMD}\)去年就讲了,然而我今年才做(捂脸) 考虑生成函数,设\(f_i\)表示最终串长为\(i\)的概率,其概率生成函数为\(F(x)=\sum f_ix^i\), ...
- Java 判断是否为回文字符串
回文字符串有两种:abcba,abccba. 代码: static boolean func(String str) { int len = str.length(); for (int i = 0; ...
- (一)老毛桃U盘启动盘制作
制作U盘启动盘前,一定要将U盘数据进行备份.U盘启动盘制作步骤: 1. 到老毛桃官网上下载U盘制作程序http://www.laomaotao.org.cn/. 2. 双击运行安装包,设置安装路径. ...
- Delphi7 IDE
- 常用插件html
1.上传模板,插件 https://github.com/kartik-v/bootstrap-fileinput 2.
- python_实现选课系统
校园管理系统 角色: 学校.学员.课程.讲师 要求: 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3 ...
- 2018牛客网暑期ACM多校训练营(第十场)A Rikka with Lowbit (树状数组)
链接:https://ac.nowcoder.com/acm/contest/148/A 来源:牛客网 Rikka with Lowbit 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C ...