18寒假最后一测+dijistra模板
题目名称 |
run |
homework |
cut |
输入 |
run.in |
homework.in |
cut.in |
输出 |
run.out |
homework.out |
cut.out |
每个测试点时限 |
1秒 |
1秒 |
2秒 |
内存限制 |
64MB |
64MB |
64MB |
测试点数目 |
10 |
10 |
10 |
每个测试点分值 |
10 |
10 |
10 |
是否有部分分 |
无 |
无 |
无 |
题目类型 |
传统 |
传统 |
传统 |
run
Background:
穿过时空隧道,小明来到了秦朝。我是谁?我在哪?
“哈哈哈,金科,发什么呆呢,你的刺杀已经失败了!”秦王躲在柱子后狂妄的笑。
一股热血在小明体内流动,他竟情不自禁地追了上去。
Description:
宫殿里一共有n根柱子,假设柱子在二维平面内的位置为(xi,yi)。金科现在在一号柱子,秦王现在在n号柱子。金科(小明)会飞檐走壁所以他从i号柱子到j号柱子的距离为min(|xi-xj|,|yi-yj|)。深知自己并不能刺杀秦王,所以小明知道事实上自己竭尽全力,也离秦王有一步之遥,所以小明想知道自己到达n号柱子的最短距离-1是多少,因为这将是他人生能走过的最后的路。
Input:
第一行一个数n。
接下来n-1行每行两个数x,y分别表示xi和yi。
Output:
一行一个数表示从1号柱子走到n号柱子的最短距离减去1的长度。
Sample input:
5
2 2
1 1
4 5
7 1
6 7
Sample output:
1
Hint:
1->2->4->5最短距离为2,答案为1。
对于30%的数据,n<=1000。
对于100%的数据,n<=200000,0<xi,yi<1e9
数据保证答案>0,不然很奇怪。。
题解:我们发现每个点分别于横纵坐标相邻的点连边就可以解决问题了,建边后直接跑最短路就可以了。最后不要忘记答案-1.(可以自己构图验证正确性)
用堆优化+dijistra的板子
#include <bits/stdc++.h> #include <algorithm> using namespace std; #define maxn 200005 #define maxm 1000005 bool vis[maxn]; int L,n,tot,head[maxn],dis[maxn]; inline void read(int &x){x=0;int f=1;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}x*=f; } struct Point{int x,y,id; }p[maxn]; struct edge{int nxt,v,w; }G[maxm]; struct rp{int id,key;rp(int a,int b){id=a, key=b;} }; bool cmp2(Point a, Point b){return a.x < b.x; } bool cmp1(Point a, Point b){return a.y < b.y; } struct cmp{bool operator()(const rp& a, const rp& b){return a.key > b.key;} };void add(int u, int v, int w){G[++tot].nxt = head[u];G[tot].w = w;G[tot].v = v;head[u] = tot;G[++tot].nxt = head[v];G[tot].w = w;G[tot].v = u;head[v] = tot; } void dijistra(){memset(dis, 127, sizeof(dis));priority_queue <rp,vector<rp>,cmp> q;q.push(rp(1, 0));dis[1] = 0;while(!q.empty()){rp u = q.top();q.pop();if(vis[u.id])continue;vis[u.id] = 1;for(int j = head[u.id]; j; j = G[j].nxt){int v = G[j].v;if(dis[v] > dis[u.id] + G[j].w){dis[v] = dis[u.id] + G[j].w;q.push(rp(v, dis[v]));}}} } int main() { freopen("run.in","r",stdin);freopen("run.out","w",stdout);read(n);for(int i = 1; i <= n; i++)read(p[i].x), read(p[i].y), p[i].id = i;sort(p+1, p+1+n, cmp2);for(int i = 1; i < n; i++)add(p[i].id, p[i+1].id, p[i+1].x - p[i].x);sort(p+1, p+1+n, cmp1);for(int i = 1; i < n; i++)add(p[i].id, p[i+1].id, p[i+1].y - p[i].y);dijistra();printf("%d\n",dis[n]-1); }
homework
Background:
小哪吒在开学前一天补作业。。。
Description:
明天就要开学了!所以小哪吒需要尽快写完作业。现在,他有n份作业需要写,因为小哪吒精通变化,他可以再变出两只手来,所以他可以同时写两份作业。小哪吒两双手写同一份作业的时间是不一样的。为了节约时间,他用火眼睛睛看出了两双手写同一份作业分别需要ai,bi的时间。同样的,为了节约时间,他不会更改做题的顺序,即他会从第一份作业一直做到第n份作业。他唯一不知道的是,他能写完作业的最短时间。你能帮他求出来吗?
Input:
第一行一个数n表示作业的数目。
接下来n行每行两个数ai,bi分别表示小哪吒两双手写这份作业的时间。
Output:
一行一个数表示写作业的最短时间。
Sample input:
3
1 3
1 3
1 3
Sample output:
3
Hint:
对于样例,用第一双手做完所有作业。
对于40%的数据,n<=20。
对于100%的数据,n<=2000。ai,bi<=3000。
题解:我们用dp[i][0/1][j]表示去做第i份作业用第0/1只手时,另外一双手还需要做j的时间才能做完作业的最小时间;
dp[i][j][k] = min( dp[i - 1][ j ][ k+a[i - 1][ j ] ] + a[i - 1][ j ], dp[i - 1][ j^1 ][ a[i - 1][ j^1 ] ] , 但我们有可能在0手有空时不一定用0手而是等1手完了用1手,
而这样当 k+a[i - 1][ j ] = 0我们刚好就去用了空闲的手,故我们反着推就可以了,因为dp[i][j][k] k=0 时有可能那只手已经休息了很久了;
注意dp[i]中第i份作业还没做,所以我们最后要加上剩下的时间
#include <bits/stdc++.h>using namespace std; #define maxn 2005 int dp[maxn][2][3005], a[maxn][2]; inline void read(int &x){x=0;int f=1;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}x*=f; }int main(){///freopen("homework.in","r",stdin);//freopen("homework.out","w",stdout);int n;read(n);for(int i = 1; i <= n; i++)read(a[i][0]), read(a[i][1]);memset(dp, 0x3f, sizeof(dp));dp[1][0][0] = dp[1][1][0] = 0;for(int i = 1; i <= n; i++)for(int j = 0; j < 2; j++)for(int k = 0; k <= 3000; k++){dp[i+1][j][max(0, k-a[i][j])] = min(dp[i+1][j][max(0, k-a[i][j])], dp[i][j][k]+a[i][j]);dp[i+1][j][max(0, a[i][j^1]-k)] = min(dp[i+1][j][max(0, a[i][j^1]-k)] , dp[i][j^1][k]+k);}int ans = 1e9;for(int j = 0; j < 2; j++)for(int k = 0; k <= 3000; k++)ans = min(ans, dp[n][j][k] + max(k, a[n][j]));printf("%d\n",ans); }
cut
Background:
伐木工Zxr非常懒惰了,所以他在伐木的时候只会找准木头被虫蛀过的腐朽的地方砍下去。
Description:
一块有N-1处被虫蛀过的地方,假设被虫蛀过的地方长度不计。这n-1个虫蛀将木头分成了n块,题目将依次给出这n块木头的长度。懒惰的zxr最多只想砍m次,并且希望可以借此把这块木头分得尽量均匀,即希望使砍伐后连续的木块中最长的尽量短。这个时候聪明的你跳了出来“我不仅能算出这个最短长度,我还能算出方案数!”
Input:
第一行两个数n,m。
接下来一行n个数分别表示这N块木头的长度。
Output:
一行两个数分别表示最短的最长长度和方案数。
Sampleinput:
3 2
1 1 10
Sampleoutput:
10 2
Hint:
两种砍的方法: (1)(1)(10)和(1 1)(10)。
对于30%的数据,n<=10,
对于100%的数据,n<=50000,
0<=m<=min(n-1,1000),1<=Li<=1000.
题解:
第一问是一个十分显然的二分,贪心Check(),很容易就能求出最小的最大长度 Len 。
第二问求方案总数,使用 DP 求解。
使用前缀和,令 Sum[i] 为前i根木棍的长度和。
令 f[i][j] 为前i根木棍中切 j 刀,并且满足最长长度不超过 Len的方案数,那么:
状态转移方程: f[i][j] = Σ f[k][j-1] ((1 <= k <= i-1) && (Sum[i] - Sum[k] <= Len))
这样的空间复杂度为 O(nm) ,时间复杂度为 O(n^2 m) 。显然都超出了限制。
下面我们考虑 DP 的优化。
1) 对于空间的优化。
这个比较显然,由于当前的 f[][j] 只与 f[][j-1] 有关,所以可以用滚动数组来实现。
f[i][Now] 代替了 f[i][j] , f[i][Now^1] 代替了 f[i][j-1] 。为了方便,我们把 f[][Now^1] 叫做 f[][Last] 。
这样空间复杂度为 O(n) 。满足空间限制。
2) 对于时间的优化。
考虑优化状态转移的过程。
对于 f[i][Now] ,其实是 f[mink][Last]...f[i-1][Last] 这一段 f[k][Last] 的和,mink 是满足 Sum[i] - Sum[k] <= Len 的最小的 k ,那么,对于从 1 到 n 枚举的i,相对应的 mink 也一定是非递减的(因为 Sum[i] 是递增的)。我们记录下 f[1][Last]...f[i-1][Last] 的和Sumf,mink 初始设为 1,每次对于i将 mink 向后推移,推移的同时将被舍弃的 p 对应的 f[p][Last] 从Sumf中减去。那么 f[i][Now] 就是Sumf的值。
这样时间复杂度为 O(nm) 。满足时间限制。
#include <bits/stdc++.h>using namespace std; #define maxn 50005 #define mod 10007 int dp[maxn][2], a[maxn], sum[maxn], L, n, m, Ml; inline void read(int &x){x=0;int f=1;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}x*=f; }bool check(int mid){int ll = 0, i = 0, group = 1, flag = 0;while(i <= n){if(ll + a[++i] <= mid)ll += a[i];else if(a[i] > mid)return false;else {group++;if(group > m + 1)return false;ll = a[i];}}return true; } void bs(){int l = Ml, r = sum[n];while(l != r){int mid = (l + r) >> 1;if(check(mid))r = mid;else l = mid+1;}L = r;//取大的printf("%d ",L); } void Dp(){int sumf = 0, mink = 0, ans = 0;int k = 0;for(int j = 0; j <= m; j++){sumf = 0; mink = 1;//一定要记得更新,忘了更新这个地方,WA了好多次for(int i = 1; i <= n; i++){if(!j){if(sum[i] <= L)dp[i][k] = 1;}else {while(mink < i && sum[i] - sum[mink] > L){sumf -= dp[mink][k^1];sumf = (sumf + mod) % mod;mink++; } dp[i][k] = sumf;} sumf = (sumf + dp[i][k^1]) % mod;}ans += dp[n][k];ans %= mod;k^=1;//滚动数组 }printf("%d\n",ans); } int main(){freopen("cut.in","r",stdin);freopen("cut.out","w",stdout);read(n),read(m);for(int i = 1; i <= n; i++){read(a[i]);Ml = max(Ml, a[i]);sum[i] = sum[i-1] + a[i];}bs();Dp(); }
转载于:https://www.cnblogs.com/EdSheeran/p/8496929.html
18寒假最后一测+dijistra模板相关推荐
- Abp 0.18.0 正式发布! -ABP CLI,新模板和其他功能
ABP CLI, v0.18版本新模板和其他功能 ABP v0.18已发布, 包含解决的80+个issue, 550+次提交. 网站更改 abp.io网站完全更新以突出ABP框架的目标和重要功能.文档 ...
- Abp v0.18.0 新版本: MVC Module 启动模板
0.18.0将于近期发布, 本文内容针对于0.18.0版本. MVC模块启动模板 可用此模板开发基于模块开发最佳实践和约定的可复用 应用程序模块 . 它同样适用于开发微服务. 如何开始? 你可以使用A ...
- 18.2.2 简单的类模板
18.2.2 简单的类模板 下面用前面的一个例子来说明,为数组定义一个类模板,该数组要对索引值进行边界检查,确保索引值是合法的.尽管标准库提供了数组模板的完整实现方式,但建立自己的数组模板有助于理解模 ...
- 2-Arduino小车测速模板安装与测试
Arduino智能小车--小车测速 准备材料 1. 测速模块 2. 3. 固定铜柱 a) 建议铜柱长度30CM,大小为M3 b) 由于铜柱导电,有些电路板 ...
- 博客摘录「 项目启动会ppt_“项目启动会”必须要汇报的18个要素(附PPT模板)| 推荐」2023年5月26日转载自:http://t.csdn.cn/z5xg8
项目经理作为项目的总负责人,项目启动会是接手项目后第一次比较正式的会议.经过前期的立项.调研.科研.设计的过程,项目的建设范围.建设周期以及建设目标逐渐地明细,但是还没有进行详细资料的整理和总结.此时 ...
- [JZOJ5666]【GDOI2018Day2模拟4.18】法力风暴(分治NTT 模板)
Description 有 2≤n≤105,0≤Ai,k≤109 2 ≤ n ≤ 10 5 , 0 ≤ A i , k ≤ 10 9 2 ≤ n ≤ 10^5 ,0 ≤ A_i ,k ≤ 10^9 S ...
- [01-23][ dcwz电影合集][10部][18:30发布][亲测]
1.08爆笑喜剧大片<火箭科学> DVD中字 2.08动作惊悚大片<法国黑金/流血的谎言> DVD中字 3.08惊悚动作片<跨越死亡线> DVD中字 4.07最新奥 ...
- kubeadm方式部署k8s集群(1.18版本,亲测可用)
文章目录 一.系统环境 1.设置系统主机名以及Host文件 2.关闭防火墙 3.关闭系统Swap 二.安装Docker 1.安装docker 2.所需镜像 三.安装kubelet.kubeadm 和 ...
- 关于模板引擎handlebars.js基本用法
说明:模板引擎主要针对于渲染DOM,取代了字符串拼接,用下面的代码亲测handlebars模板引擎比字符串拼接渲染DOM慢了20ms, 这里配置一个在线DEMO,简单说明下handlebars.js的 ...
最新文章
- NYOJ 138 找球号(二)哈希表
- js 静止f1到f12 和屏蔽鼠标右键
- CSDN 开学见面礼!3 周带你 Get 大厂工程师基础能力
- GO编程程序员修炼秘籍:十本经典书单
- Python3 中你知道有多少错误和异常
- Bootstrap CSS 编码规范之注释
- Windows环境下log4cxx的编译及使用(转载)
- 拓端tecdat:Python集成学习:自己编写构建AdaBoost分类模型可视化决策边界及sklearn包调用比较
- redisconnectionfactory 没有这个bean_浅析Spring中bean的作用域
- Latex所有常用数学符号整理
- Android测试总结
- 电脑硬盘怎么分区?C盘/D盘/E盘......快来创建自己的DIY磁盘吧!
- 生产大数据集群架构图
- EasyExcel导出合并单元格
- 小白通过JDBC在AndroidStudio一步步来访问MYSQL数据库
- FlashVml2.0(WEB上的PhotoShop+Flash、VML最强开发工具)[推荐]
- 青龙面板-花花阅读6.25 最新修复版
- #300. 【CTSC2017】吉夫特
- 用R语言绘制ROC曲线
- R语言使用caret包的train函数构建adaboost模型、模型调优、自定义设置trainControl函数和tuneLength参数