[题解]CF Round #384 (Div.2)
来源:互联网 发布:淘宝卖鞋正品的店铺 编辑:程序博客网 时间:2024/04/30 11:28
743A:Vladik and flights
题意简述
有
在同家公司的机场间行动不耗代价,在不同公司的机场间移动,从
问从
数据范围
思路
水。
代码
#include<cstdio>using namespace std;int n,a,b;char st[100010];int main(){ scanf("%d%d%d",&n,&a,&b); scanf("%s",st+1); if (st[a]==st[b]) printf("0"); else printf("1"); return 0;}
743B:Chloe and the sequence
题意简述
数列
第
求第
数据范围
思路
经过观察可以发现。
答案即为
代码
include<cstdio>using namespace std;int n;long long k;int main(){ scanf("%d%I64d",&n,&k); for (int i=0;i<=n;i++) if (k&(1LL<<i)) { printf("%d",i+1); break; } return 0;}
743C:Vladik and fractions
题意简述
给出
数据范围
思路
这个题比较有意思…
首先
然后瞬间联想到裂项项消……
于是答案就是
一看
代码
#include<cstdio>using namespace std;int n;int main(){ scanf("%d",&n); if (n==1) printf("-1"); else printf("%d %d %d\n",n,n+1,n*(n+1)); return 0;}
743D:Chloe and pleasant prizes
题意简述
给出一棵
求两个不相交的子树,权值和的最大值。
如果没有这样的方案,输出
数据范围
思路
树形DP。
DP出
以一个节点为根的答案一定是它所有孩子的
所有的答案扫一遍就行了。
注意一条链的情况无解。
代码
#include<cstdio>#include<cstring>#include<iostream>using namespace std;#define INF 1LL<<60 struct edge{ int s,t,next;}e[400010];int head[200010],cnt;void addedge(int s,int t){ e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++; e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;}int n,u,v;long long sum[200010],mx[200010];int size[200010],val[200010];long long ans=-INF,se;void dfs(int node,int lastfa){ sum[node]=val[node]; size[node]=0; for (int i=head[node];i!=-1;i=e[i].next) if (e[i].t!=lastfa) { dfs(e[i].t,node); sum[node]+=sum[e[i].t]; size[node]++; } mx[node]=-INF; se=-INF; for (int i=head[node];i!=-1;i=e[i].next) if (e[i].t!=lastfa) { if (mx[e[i].t]>mx[node]) { se=mx[node]; mx[node]=mx[e[i].t]; } else if (mx[e[i].t]>se) se=mx[e[i].t]; } if (size[node]>1) ans=max(ans,mx[node]+se); mx[node]=max(mx[node],sum[node]);}int main(){ scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&val[i]); memset(head,0xff,sizeof(head)); cnt=0; for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); addedge(u,v); } dfs(1,1); if (ans==-INF) printf("Impossible"); else printf("%I64d",ans); return 0;}
743E:Vladik and cards
题意简述
给出
问最长的满足如下条件的子序列长度:
1.子序列中所有相同元素相邻。
2.子序列中任意两种元素的个数之差的绝对值
数据范围
思路
二分+DP。
我们可以发现,所有元素的出现次数之可能为
所有我们可以二分这个
如何DP?
首先预处理。
DP数组
1.
2.取
3.取
据此转移就可以了。
时间复杂度
代码
#include<cstdio>#include<iostream>#include<cstring>using namespace std;int f[1010][260];int n,lim,l,r,mid,tmp,ans,now;int seq[1010],ord[1010],cnt[10],pos[10][1010];bool judge(int x){ tmp=0; memset(f,0xef,sizeof(f)); f[0][0]=0; for (int i=1;i<=n;i++) for (int j=0;j<=lim;j++) { f[i][j]=f[i-1][j]; if (j&(1<<seq[i])) { now=ord[i]; if (x>0&&now-x+1>=1) f[i][j]=max(f[i][j],f[pos[seq[i]][now-x+1]-1][j^(1<<seq[i])]+x); if (now-x>=1) f[i][j]=max(f[i][j],f[pos[seq[i]][now-x]-1][j^(1<<seq[i])]+x+1); } } if (x==0) for (int i=0;i<=lim;i++) tmp=max(tmp,f[n][i]); else tmp=f[n][lim]; return tmp>0;}int main(){ scanf("%d",&n); lim=(1<<8)-1; for (int i=1;i<=n;i++) { scanf("%d",&seq[i]); seq[i]--; } for (int i=1;i<=n;i++) { ord[i]=++cnt[seq[i]]; pos[seq[i]][cnt[seq[i]]]=i; } l=0,r=n/8; while (l<=r) { mid=(l+r)>>1; if (judge(mid)) ans=tmp,l=mid+1; else r=mid-1; } printf("%d",ans); return 0;}
- [题解]CF Round #384 (Div.2)
- [题解]CF Round #385 (Div.2)
- [题解]CF Round #386 (Div.2)
- CF Round #256 (Div. 2)
- CF Round #260 (Div 2)
- CF Round #439 (Div 2)
- CF Round#240题解
- CF#247(Div. 2)部分题解
- cf Round #202 (div.2) C ------------ Mafia
- CF Round #240 (Div. 2) C
- CF Round #240 (Div. 2) D
- CF Round #254 (Div. 2) E
- 【CF】Codeforces Round #301 (Div. 2) ABCDE
- 【CF】Codeforces Round #361 (Div. 2)
- CF-Codeforces Round #377 (Div. 2)
- CF Round 415 Div.2解题报告
- CF Round #428( Div.2)BCDE
- [CF刷题]Codeforces Round #443 (Div. 2)
- 滚动条
- 短信验证码
- 设计模式之单例模式
- jsp中正确显示时间格式
- jquery简单实现tab选项卡效果
- [题解]CF Round #384 (Div.2)
- 在Spring中使用JTA事务管理
- 聚焦2016世界移动大会
- 重装系统的简易方法
- 远程服务器怎么连接
- windows curl命令详解
- 第十六周练习--点结构体
- Android 最简单的rxjava遍历集合写法
- 顺序栈操作