[USACO 2018 Feb Gold] Tutorial
Link:
A:
$dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解
状态数$O(n^3)$
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=,INF=<<;
int n,dat[MAXN],dp[MAXN][MAXN][MAXN]; int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&dat[i]);
for(int i=;i<MAXN;i++)
for(int j=;j<MAXN;j++)
for(int k=;k<MAXN;k++)
dp[i][j][k]=INF; if(dat[]!=) dp[][][]=;
else dp[][][]=;
for(int i=;i<n;i++)
for(int j=;j<=i;j++)
for(int k=;k<=i-j;k++)
if(dp[i][j][k]!=INF)
{
dp[i+][j][k+]=min(dp[i+][j][k+],dp[i][j][k]+(dat[i+]!=k+));
dp[i+][j+][]=min(dp[i+][j+][],dp[i][j][k]+(dat[i+]!=));
}
for(int i=;i<=n;i++)
{
int res=INF;
for(int j=;j<=n;j++)
res=min(res,dp[n][i][j]);
printf("%d\n",res);
}
return ;
}
Problem A
B:
对于每一个节点分别计算其上方和下方的答案,其中下方答案明显可以一遍$dfs$
上方答案我一开始是$O(树高)$求的,明显会被卡……
其实可以再做一遍$dfs$,用父节点除去该棵子树的贡献再加上走到父节点的贡献即可
注意特殊处理叶子结点
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
char s[MAXN][];
struct edge{int nxt,to;}e[MAXN<<];
int n,x,head[MAXN],len[MAXN],f[MAXN],num[MAXN],tot;
ll sum[MAXN],cnt[MAXN],tmp,res[MAXN],mn=1ll<<,lf; void add_edge(int x,int y)
{
e[++tot]={head[x],y};head[x]=tot;
e[++tot]={head[y],x};head[y]=tot;
} void dfs1(int x,int anc)
{
for(int i=head[x];i;i=e[i].nxt)
{
if(e[i].to==anc) continue;
f[e[i].to]=x;dfs1(e[i].to,x);
cnt[x]+=cnt[e[i].to];
sum[x]+=sum[e[i].to]+cnt[e[i].to]*(len[e[i].to]+);
}
} void dfs2(int x,int anc)
{
for(int i=head[x];i;i=e[i].nxt)
{
if(e[i].to==anc||!num[e[i].to]) continue;
res[e[i].to]=sum[e[i].to];
res[e[i].to]+=(res[x]-sum[e[i].to]-cnt[e[i].to]*(len[e[i].to]+));
res[e[i].to]+=*(lf-cnt[e[i].to]);mn=min(mn,res[e[i].to]);
dfs2(e[i].to,x);
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s%d",s[i]+,&num[i]);
len[i]=strlen(s[i]+);
for(int j=;j<=num[i];j++)
scanf("%d",&x),add_edge(x,i);
if(!num[i]) cnt[i]=,len[i]--,lf++;
}
dfs1(,);
res[]=mn=sum[];
dfs2(,); printf("%lld",mn);
return ;
}
Problem B
C:
好像和前面一题差不多?
可以离线从小到大加点用$set$和$multiset$维护当前点集和答案
不过官网上的标程常数更小:反向从大到小加点,用链表维护当前最大空隙
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
multiset<int,greater<int> > mx;
set<int> s;set<int>::iterator it;
int n,m,res[MAXN];P sw[MAXN];
struct Query{int s,d,id;}bt[MAXN];
bool cmp(Query a,Query b){return a.s<b.s;} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&sw[i].X),sw[i].Y=i;
for(int i=;i<=m;i++)
scanf("%d%d",&bt[i].s,&bt[i].d),bt[i].id=i;
sort(sw+,sw+n+);sort(bt+,bt+m+,cmp); int lst=,pre,nxt;
s.insert();s.insert(n);mx.insert(n-);
for(int i=;i<=n;i++)
{
while(sw[lst].X<=bt[i].s&&lst<=n)
{
if(sw[lst].Y!=&&sw[lst].Y!=n)
{
it=s.lower_bound(sw[lst].Y);
nxt=*it;pre=*(--it);
mx.erase(mx.find(nxt-pre));
mx.insert(nxt-sw[lst].Y);mx.insert(sw[lst].Y-pre);
}
s.insert(sw[lst].Y);lst++;
}
res[bt[i].id]=(*mx.begin()<=bt[i].d);
}
for(int i=;i<=m;i++)
printf("%d\n",res[i]);
return ;
}
Problem C
如果将问题转化为在原序列中大量删除的,手写链表即可
[USACO 2018 Feb Gold] Tutorial的更多相关文章
- [USACO 2018 Jan Gold] Tutorial
Link: USACO 2018 Jan Gold 传送门 A: 对于不同的$k$,发现限制就是小于$k$的边不能走 那么此时的答案就是由大于等于$k$的边形成的图中$v$所在的连通块除去$v$的大小 ...
- [USACO 2017 Feb Gold] Tutorial
Link: 传送门 A: 分层图最短路(其实就是最短路转移时多记录一维的数据 #include <bits/stdc++.h> using namespace std; #define X ...
- [USACO 2018 Open Gold] Tutorial
Link: 传送门 A: 对于每一条分割线,设本不应在其左侧的个数为$x$ 重点要发现每次一来一回的操作恰好会将一对分别应在左/右侧的一个数从右/左移过去 这样就转直接用树状数组求出最大的$x$即可 ...
- [USACO 2017 Dec Gold] Tutorial
Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...
- [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】
传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=118 传送门2:http://www.lydsy.com/JudgeOn ...
- BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution
权限题,不给传送门啦!在学校OJ上交的.. 有些不开心,又是一道贪心,又是一个高级数据结构的模板,又是看了别人的题解还写崩了QAQ,蒟蒻不需要理由呀. 正经题解: 首先,我们可以由「显然成立法」得出, ...
- BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution
标题效果:一个N积分m无向图边.它可以是路径k右边缘值变0,确定此时1-n最短路径长度. Sol:我以为我们考虑分层图,图复制k+1部分,每间0~k一层.代表在这个时候已经过去"自由边缘&q ...
- bzoj3939 【USACO 2015 FEB GOLD 】cow hopscotch
Description 就像人类喜欢玩"跳房子"的游戏,农民约翰的奶牛已经发明了该游戏的一个变种自己玩.由于笨拙的动物体重近一吨打,牛跳房子几乎总是以灾难告终,但这是没有阻止奶牛几 ...
- BZOJ1782[USACO 2010 Feb Gold 3.Slowing down]——dfs+treap
题目描述 每天Farmer John的N头奶牛(1 <= N <= 100000,编号1…N)从粮仓走向他的自己的牧场.牧场构成了一棵树,粮仓在1号牧场.恰好有N-1条道路直接连接着牧场, ...
随机推荐
- 【Luogu】 P3928 SAC E#1 - 一道简单题 Sequence2
[题目]洛谷10月月赛R1 提高组 [算法]递推DP+树状数组 [题解]列出DP递推方程,然后用树状数组维护前后缀和. #include<cstdio> #include<cstri ...
- Remmarguts' Date(POJ2449+最短路+A*算法)
题目链接:http://poj.org/problem?id=2449 题目: 题意:求有向图两点间的k短路. 思路:最短路+A*算法 代码实现如下: #include <set> #in ...
- windows7_常用操作终端操作
查看环境变量:set 添加环境变量:set aa = 88 删除环境变量:set aa = 查看ip配置:ipconfig 查看全局环境变量配置:path 查看当前目录文件:dir 进入E盘:E: 进 ...
- JAVA 非对称加密算法RSA
非对称加密算法 RSA过程 : 以甲乙双方为例 1.初始化密钥 构建密钥对,生成公钥.私钥保存到keymap中 KeyPairGenerator ---> KeyPair --> RSAP ...
- net_dev_init
Kernel: 4.12.6 网络设备初始化,主要包括初始化softnet_data,注册收发包软中断等: static int __init net_dev_init(void) { int i, ...
- 通过call_usermodehelper()在内核态执行用户程序【转】
转自:http://edsionte.com/techblog/archives/category/linux%E5%86%85%E6%A0%B8%E7%BC%96%E7%A8%8B 背景 如何在Li ...
- 图论-强连通分量-Tarjan算法
有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...
- 图论-最近公共祖先-离线Tarjan算法
有关概念: 最近公共祖先(LCA,Lowest Common Ancestors):对于有根树T的两个结点u.v,最近公共祖先表示u和v的深度最大的共同祖先. Tarjan是求LCA的离线算法(先存储 ...
- mybatis源码阅读(动态代理)
这一篇文章主要是记录Mybatis的动态代理学习成果,如果对源码感兴趣,可以看一下上篇文章 https://www.cnblogs.com/ChoviWu/p/10118051.html 阅读本篇的 ...
- redis使用教程
一.redis 的安装 官方就是个坑:只说make一下即可用,确实可以用,我以为装好了,结果好多问题: 安装步骤:make => make test => make install 1 ...