2018 ACM-ICPC World Finals - Beijing

2018 ACM-ICPC World Finals - Beijing


A. Catch the Plane

\(dp[v_i,t_i]\)表示时刻\(t_i\)\(v_i\)点,到达终点的最大概率,那么转移方程为:
\(dp[(v_i,t_i)] = max(P_{ij}*dp[(v_{j+1},t_{j+1})] + (1-Pij)*dp[(v_{i+1},t_{i+1})])\)
\(dp[(v_i,t_i)] = max(dp[v_{i+1},t_{i+1}])\)
其中\((v_i,t_i)\)的一个后继状态为\((v_j,t_j)\)两个状态之间的转移概率为\(P_{ij}\),第一种转移:沿\(P_{ij}\)这个方向转移,以及继续留在这个点等待下次转移(\((v_{i+1},t_{i+1})\)为同一位置下与\(t_i\)最接近的下一个时间);第二种转移是:直接选择继续等待的概率。想出这些后,以为可以愉快的ac了。然而调到早上7点。。。才弄好

  • 问题一:%I64d读1e18,蜜汁爆了,换了几个编译器才发现。。。
  • 问题二:为简化代码省略了讨论,导致后面一个点wa
  • 问题三:起点和终点要单独加进去,导致后面一个点wa
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long double LD;
typedef unsigned long long ll;
const int N = 5e6 + 100;
using namespace std;
struct node {int x; ll t;node(){}node(int a,ll b) {x=a,t=b;}bool operator < (const node a) const {if(t==a.t) return  x<a.x;return t < a.t;}
};
bool cmp(node a,node b) {if(a.x==b.x) return a.t < b.t;return a.x < b.x;
}
bool cmp0(node a,node b) {if(a.t==b.t) return a.x > b.x;return a.t < b.t;
}
vector<node> v;
map<node,int> id;
node fid[N];
int cnt;int nxt[N];
LD dp[N];
vector< pair<int,LD> > E[N];
void nwnode(node a) {if(id[a]!=0) return;++cnt;fid[cnt] = a;id[a] = cnt;
}
void add(int a,int b,LD p){E[a].pb(make_pair(b,p));
}
int n,m;
ll k;int main() {int f=0;ll MX=0,MN=1000000000000000002LL;scanf("%d%d%llu",&m,&n,&k);rep(i,1,m) {int a,b;ll s,t; double p;scanf("%d %d %llu %llu %lf",&a,&b,&s,&t,&p);if(t<=k){nwnode(node(a,s));nwnode(node(b,t));add(id[node(a,s)],id[node(b,t)],(LD)p);v.pb(node(a,s));v.pb(node(b,t));if(b == 1LL) {dp[id[node(b,t)]] = 1.0;MX = max(t,MX);}if(a==0){if(!f)MN=t;else MN=min(MN,t);f=1;}}}nwnode(node(1,MX));nwnode(node(1,k));nxt[id[node(1,MX)]] = id[node(1,k)];dp[id[node(1,k)]] = 1.0;v.pb(node(1,k));add(id[node(1,MX)],id[node(1,k)],1.0);nwnode(node(0,0));v.pb(node(0,0));nxt[id[node(0,0)]] = id[node(0,MN)];add(id[node(0,0)],id[node(0,MN)],1.0);sort(v.begin(),v.end(),cmp);for(int i=v.size()-2;i>=0;--i) {if(v[i].x==v[i+1].x){if(v[i].t == v[i+1].t) nxt[id[v[i]]] = nxt[id[v[i+1]]];else nxt[id[v[i]]] = id[v[i+1]];}}sort(v.begin(),v.end(),cmp0);for(int i=v.size()-1;i>=0;--i) if(dp[id[v[i]]]==0){LD mx = 0;int t = id[v[i]];for(int j=0;j<E[t].size();++j) {if(fid[nxt[E[t][j].first]].x == fid[E[t][j].first].x && fid[nxt[t]].x == fid[t].x && dp[nxt[t]]!=0 && dp[nxt[E[t][j].first]]!=0 )mx = max(mx, E[t][j].second*dp[nxt[E[t][j].first]] + (1.0-E[t][j].second)*dp[nxt[t]]);else if(fid[nxt[E[t][j].first]].x == fid[E[t][j].first].x && dp[nxt[E[t][j].first]]!=0)mx = max(mx, E[t][j].second*dp[nxt[E[t][j].first]]);else if(fid[nxt[t]].x == fid[t].x && dp[nxt[t]]!=0)mx = max(mx, (1.0-E[t][j].second)*dp[nxt[t]]);}if(fid[nxt[t]].x == fid[t].x)mx = max(mx, dp[nxt[t]]);dp[t] = mx;}printf("%.10f\n",(double)dp[id[node(0,0)]]);return 0;
}

B. Comma Sprinkler

这题没什么难度,把单词取出来直接搜索即可。

#include <bits/stdc++.h>
#define pb push_back
typedef long long ll;
const int N = 1000100;
using namespace std;
string s, word[N];
int cnt;
void chai(string s) {int n = s.size();cnt = 1;for(int i=0;i<n;++i) {if(s[i]==' '){word[cnt] += ' ';++cnt;}elseword[cnt]+=s[i];}
}
map< string,vector<string> > pre,last;
string delco(string s) {string t;t.clear();for(auto c: s) if(c>='a'&&c<='z') t+=c;return t;
}
int iscolst(string s) {int t = s.size()-1;while(t>=0){if(s[t]==',')return 1;--t;}return 0;
}
int isbiaolst(string s) {int t = s.size()-1;while(t>=0){if(s[t]=='.'||s[t]==',')return 1;--t;}return 0;
}
map<string,bool> vispre,vislst;
void X(string s);
void Y(string s);
void X(string s) {vislst[s] = 1;for(int x=0;x<last[s].size();++x) if(!vispre[last[s][x]]) Y(last[s][x]);
}
void Y(string s) {vispre[s] = 1;for(int x=0;x<pre[s].size();++x) if(!vislst[pre[s][x]]) X(pre[s][x]);
}
string update(string s) {s+=',';int t=s.size()-1;swap(s[t],s[t-1]);return s;
}
int main() {getline(cin,s); chai(s);for(int i=2;i<=cnt;++i) if(!isbiaolst(word[i-1])){pre[delco(word[i])].pb(delco(word[i-1]));}for(int i=1;i<cnt;++i) if(!isbiaolst(word[i])){last[delco(word[i])].pb(delco(word[i+1]));}for(int i=1;i<cnt;++i) {string t = delco(word[i]);if(!vislst[t]&&iscolst(word[i]))X(t);}for(int i=2;i<=cnt;++i) {string t=delco(word[i]);if(!vispre[t]&&iscolst(word[i-1])) Y(t);}for(int i=1;i<=cnt;++i) {string t = delco(word[i]);if(vislst[t]&&!isbiaolst(word[i]))cout << update(word[i]);elsecout << word[i];}puts("");return 0;
}

F. Go with the Flow

把单词的长度记录下来,模拟放单词,把所有位置上是空格的位置按从上到下存起来。顺序dp求出每个位置向上最长走多远,dp过程中取最大值即可,这样复杂度与空格数成正比,看大佬代码学习了一下,巧妙地解决了dp数组的开法用一维存,这样空间就不随着宽度变化。一开始写的暴力bfs炸的妥妥的。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
#define MP make_pair
#define fr first
#define sc second
typedef long long ll;
const int N = 5600;
using namespace std;
int n,L[N],len;
char s[88];
PII A[N];
int cnt,f[N*188];void cal_A(int w) {int x=1,y=0;cnt=0;rep(j,1,n) {if(y+L[j]<=w){if(y)A[++cnt]=MP(x,y);y+=L[j]+1;}else {++x;y=L[j]+1;}}
}
int cal_id(int x,int y,int m) {if(x<1)return 0;if(y<1||y>m)return 0;return (x-1)*m + y;
}
int main() {int MX = 0;scanf("%d",&n);for(int i=1;i<=n;++i) {scanf(" %s",s);L[i]=strlen(s);MX = max(MX,L[i]);len += L[i];}len += (n-1);int ans=0,ans1=0,tmp;rep(i,MX,len) {cal_A(i);tmp = 0;rep(j,1,cnt){int x=A[j].fr, y=A[j].sc;f[cal_id(x,y,i)] = max(f[cal_id(x-1,y-1,i)],f[cal_id(x,y,i)]);f[cal_id(x,y,i)] = max(f[cal_id(x-1,y,i)],f[cal_id(x,y,i)]);f[cal_id(x,y,i)] = max(f[cal_id(x-1,y+1,i)],f[cal_id(x,y,i)]);++f[cal_id(x,y,i)];tmp = max(tmp,f[cal_id(x,y,i)]);}if(tmp>ans){ans=tmp;ans1=i;}rep(j,1,cnt)f[cal_id(A[j].fr,A[j].sc,i)]=0;}printf("%d %d\n",ans1,ans);return 0;
}

K. Wireless is the New Fiber

贪心,首先答案是一棵树,既有n-1条边,所以要减少的总边数固定,所以我们尽量要改变度数大的点,换一句话一定先满足分叉少的。现在考虑如何满足,注意到度数为1的点是很特殊的,我们一定要先满足他们,并且最好他们不互相连接,那就把他们接在其他度数较小的点上,显然最好不接满。我们已经确定,如果有度为1的点,一定要先满足它,那么考虑如何把度非1的点转换为度为1的点,显然就是把度数为1的点接上去使他恰好多余一个位置,这些点组成的集合便是一个新的度为1的点,如此反复到无法产生新的度为1的点集。接下来我们仍然优先满足度数小的点,先把所有的1接上去,剩下的位置怎么办,我用度数最大的点接上去,把他们当作度数为1的点,为什么?因为这些点的度数最大,可以尽可能的把减少的边用在他们身上,重复上述操作,直到不足以产生新的度数为1的点集。最后把剩余的点全部加到当前节点上。如果最终有多个的度数为1的点集,那把他们任意连成一棵树树即可。这题的贪心,我之前一直在胡写,也没证明出来做法的正确性。。GG。。。。膜了大佬的写法。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define pb push_back
typedef long long ll;
const int N = 10000 + 10;
using namespace std;
int n,m,d[N];
vector<int> G[N];
void add(int u,int v) {G[u].pb(v);}
struct node {int id,d;node(){}node(int a,int b){id=a,d=b;}
}a[N];
int b[N];
int cnt,cnt0;
bool cmp(node a,node b) {return a.d < b.d;}
vector<int> v;
int main() {scanf("%d%d",&n,&m);rep(i,1,m) {int x,y;scanf("%d%d",&x,&y);++d[x],++d[y];}for(int i=0;i<n;++i) a[cnt++] = node(i,d[i]);sort(a,a+cnt,cmp);for(int i=0;i<cnt;++i) {if(a[i].d==1) v.push_back(a[i].id);else if(v.size() >= a[i].d-1){for(int j=0;j<a[i].d-1;++j) {add(a[i].id,v[v.size()-1]);v.pop_back();}v.push_back(a[i].id);}else if(v.size()+cnt-i-1>=a[i].d-1){for(int j=0;j<v.size();++j) {add(v[j],a[i].id);}for(int j=0;j<a[i].d-1-v.size();++j){add(a[i].id,a[--cnt].id);}v.clear();v.push_back(a[i].id);}else {for(int j=0;j<v.size();++j){add(a[i].id,v[j]);}for(int j=i+1;j<cnt;++j){add(a[i].id,a[j].id);}v.clear();break;}}if(v.size()>0){for(int i=1;i<v.size();++i){add(v[0],v[i]);}}for(int i=0;i<n;++i){for(int j=0;j<G[i].size();++j) {--d[i],--d[G[i][j]];}}int num=0;rep(i,0,n-1)if(d[i])++num;printf("%d\n",num);printf("%d %d\n",n,n-1);rep(i,0,n-1){rep(j,0,(int)G[i].size()-1) {printf("%d %d\n",i,G[i][j]);}}return 0;
}

转载于:https://www.cnblogs.com/RRRR-wys/p/9236861.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320746.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解析Visual C# 7.2中的private protected访问修饰符

去年12月份&#xff0c;随着Visual Studio 2017 Update 15.5的发布&#xff0c;Visual C#迎来了它的最新版本&#xff1a;7.2. 在这个版本中&#xff0c;有个让人难以理解的新特性&#xff0c;就是private protected访问修饰符&#xff08;Access Modifier&#xff09;。至此&a…

【Floyed】廉价最短路径

廉价最短路径 题目大意&#xff1a; 一个图中&#xff0c;在满足最短路的前提下&#xff0c;求最小代价 原题&#xff1a; 题目描述 图是由一组顶点和一组边组成的。一条边连接两个顶点。例如&#xff0c;图1表示了一个有4个顶点V、5条边的图。图中&#xff0c;每条边e是有…

CF401C-Team【构造】

正题 题目链接:https://www.luogu.com.cn/problem/CF401C 题目大意 构造一个序列包含nnn个000和mmm个111且不含有连续两个000和连续三个111。 解题思路 考虑用110110110和101010来构造序列即可。 codecodecode #include<cstdio> #include<cstring> #include<…

哈希学习笔记

hash学习笔记 常用函数: $ hash[i] \sum _{ji} ^{len-1} {s[j]*X^{j-i}}, X ≥ |字符集| $ 取多个模&#xff0c;对于一个子串\(s[i]s[i1]..s[j]\)的\(hash hash[i] - hash[j1]*X^{j-i1}\)&#xff0c;预处理\(hash[i]\)以及\(X^i\)即可\(O(1)\)求出所有的子串hash值一般运用…

Net Core集成Exceptionless分布式日志功能以及全局异常过滤

相信很多朋友都看过我的上篇关于Exceptionless的简单入门教程[asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程][https://www.cnblogs.com/yilezhu/p/9193723.html] 上篇文章只是简单的介绍了Exceptionless是什么&#xff1f;能做什么呢…

【斐波那契】【前缀和】无限序列

无限序列 题目大意&#xff1a; 有这样一个规则&#xff1a;1.把“1”变成“10” 2.把“0”变成“1” 一个序列的第一位是“1” 然后是&#xff1a;“10”&#xff0c;“101”…… 序列无限次操作后会得到“1011010110110101101……” 问某一个区间内有多少个“1” 原题&…

CF496E-Distributing Parts【平衡树,贪心】

正题 题目链接:https://www.luogu.com.cn/problem/CF496E 题目大意 nnn个[li,ri][l_i,r_i][li​,ri​]&#xff0c;mmm个[ai,bi,ki][a_i,b_i,k_i][ai​,bi​,ki​]表示可以覆盖掉kik_iki​个ai≤li≤ri≤bia_i\leq l_i\leq r_i\leq b_iai​≤li​≤ri​≤bi​的区间&#xff0…

kmp学习笔记

kmp&#xff0c;扩展 kmp 学习笔记 说再前边 字符串水平基本为0&#xff0c;学了第4遍KMP了&#xff0c;总是忘。。。网上资料很多&#xff0c;就不详细讲解了。抄的kuangbin神犇模板 kmp 一些知识 循环节大小&#xff1a;n - nxt[n]模板[HDU2087] 下标从0开始 nxt[i] 为满足p[…

AspNetCore微服务下的网关-Kong(一)

Kong是Mashape开源的高性能高可用API网关和API服务管理层。它基于OpenResty&#xff0c;进行API管理&#xff0c;并提供了插件实现API的AOP。Kong在Mashape 管理了超过15,000 个API&#xff0c;为200,000开发者提供了每月数十亿的请求支持。本文将从架构、API管理、插件三个层面…

【DP】删数

删数 题目大意&#xff1a; 有一堆数x1,x2……xnx_1,x_2……x_nx1​,x2​……xn​&#xff0c;可以从两边删除一些数删除i~k的价值是∣xi–xk∣∗(k−i1)|xi – xk|*(k-i1)∣xi–xk∣∗(k−i1)&#xff0c;求价值最大是多少 原题&#xff1a; 题目描述 有N个不同的正整数数…

CF396B-On Sum of Fractions【数学】

正题 题目链接:https://www.luogu.com.cn/problem/CF396B 题目大意 定义 v(n)v(n)v(n)表示≤n\leq n≤n的最大整数u(n)u(n)u(n)表示>n>n>n的最小整数 求∑i2n1v(i)u(i)\sum_{i2}^n\frac{1}{v(i)u(i)}i2∑n​v(i)u(i)1​ 解题思路 有式子b−aab1a−1b\frac{b-a}{ab…

拥抱开源, Office 365开发迎来新时代

这个话题我曾经写过文章&#xff0c;也在一些场合做过专题分享。今天换一种方式&#xff0c;你可以直接点击下面这个小程序&#xff0c;用十分钟左右的时间&#xff0c;听我再讲一讲吧。你需要在微信里面才能看到下面的小程序链接&#xff0c;并且可以直接点击你可以打开该文档…

Wannafly挑战赛19

Wannafly挑战赛19 A. 队列Q 需要支持把一个元素移到队首&#xff0c;把一个元素移到队尾&#xff0c;移到队首就直接放到队首前面那个位置&#xff0c;原位置标为0&#xff0c;队尾同理。 #include <bits/stdc.h> #define rep(i,a,b) for(int ia;i<b;i) typedef long …

【模拟】俄罗斯方块

俄罗斯方块 题目大意&#xff1a; 在俄罗斯方块中&#xff0c;放一块方块进一个图中&#xff0c;问刚好和上的可能性有多少种 原题&#xff1a; 题目描述 相信大家都玩过“俄罗斯方块”游戏吧&#xff0c;“俄罗斯方块”是一个有趣的电脑小游戏&#xff0c;现有一个有C列、…

实体类的动态生成(一)

前言在应用开发中&#xff0c;通常都会涉及各种 POJO/POCO 实体类&#xff08;DO, DTO, BO, VO&#xff09;的编写&#xff0c;有时这些实体类还需要实现 INotifyPropertyChanged 接口以支持属性变更通知&#xff0c;一般我们都会手写这些代码或者通过工具根据数据库表定义抑或…

CF525D-Arthur and Walls【贪心】

正题 题目链接:https://www.luogu.com.cn/problem/CF525D 题目大意 n∗mn*mn∗m的网格&#xff0c;有∗*∗和...&#xff0c;每次可以将∗*∗改成...。求最少操作使得每个...所在的联通块都是一个矩形。 解题思路 因为一个大矩形中每一个小块也是一个矩形&#xff0c;反之同理…

SoundHound Inc. Programming Contest 2018[C. Ordinary Beauty]

SoundHound Inc. Programming Contest 2018 -Masters Tournament-[C. Ordinary Beauty] 打表找规律的。 \(n 1\) 时&#xff0c; \(ans m\)\(n 2\) 时&#xff0c; \(ans 2*(m-1)*2^{m-2}\)\(n 3\) 时&#xff0c; 1) \(d 0, ~~ ans 3*(m-1)*3^{m-2}\) 2) \(d 1, ~~ an…

初一模拟赛总结(2019.6.1)

成绩&#xff1a; 注&#xff1a;rankrankrank是有算其他dalaodalaodalao的 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4333hkyhkyhky360360360100100100606060100100100100100100444lyflyflyf320320320100100100202020100100100100100100555lthlthlth1…

实体类的动态生成(二)

前言实体类的动态生成&#xff08;一&#xff09;由于采用字典的方式来保存属性变更值的底层设计思想&#xff0c;导致了性能问题&#xff0c;虽然.NET的字典实现已经很高效了&#xff0c;但相对于直接读写字段的方式而言依然有巨大的性能差距&#xff0c;同时也会导致对属性的…

CF442C-Artem and Array【贪心】

正题 题目链接:https://www.luogu.com.cn/problem/CF442C 题目大意 nnn个数&#xff0c;删除一个数可以获得左右两边最小值的价值&#xff0c;求删除所有数的最大价值。 解题思路 对于一个位置如果它左右两边都比它高那么这个位置一定删除&#xff0c;然后序列会呈一个单峰状…