USACO的题目还是很不错的,就是可惜OJ方面不多,不过搞到了BZOJ的root,这样就能较方便地提交了。
为了方便看题,搞来一本题典,100题,希望能把大多数题目都搞定 //由于版权问题,不能公开这本题典,不过题目已经在列表里了。
按照我的情况,简单题就不发了,容易上当的和难题会发上来
先来一发总表(14.2.6更新)
|
题号 |
题目和难度 |
提示 |
勘误或注意事项 |
第0题 |
★☆☆☆☆ 负二进制 (THE MORONIC COWMPOUTER, 2006 FEB) |
和其他转进制一样做,要注意mod出来可能是负的 |
|
第1题 |
★★☆☆☆ 数的幂次 (CRUEL MATH TEACHER, 2009 FEB) |
快速幂套高精度即可 |
|
第2题 |
★★★☆☆ 分数变小数 (FRACTIONS TO DECIMALS, 1993 QUALIFYING ROUND) |
循环判断,用数组存储每次的余数,当余数出现过一次就停止 |
输出格式:每行只输出76个字符 |
第3题 |
★★★☆☆ 丑数 (HUMBLE NUMBERS, CHAMPIONSHIP) |
假设已算出前n个,第n+1个一定是前n个中的一个和一个素数的积 |
|
第4题 |
★☆☆☆☆ 公司利润 (PROFITS, 2011 JAN) |
最大连续和 |
|
第5题 |
★☆☆☆☆ 接住苹果 (APPLE CATCHING, 2004 NOV) |
dp[n][k]为前n个点正好移动k次的答案 |
|
第6题 |
★★☆☆☆ 方形牛棚 (BIG BARN, 1997 FALL) |
用平方时间算出每个点在左方和上方的限制,然后就能DP了 |
|
第7题 |
★★★☆☆ 滑雪课程 (SKI LESSONS, 2009 OPEN) |
将课程按结束时间排序,预处理能力值x的情况下最小时间,dp(i,j)为时间为j,前i个课程的答案 |
|
第8题 |
★★★☆☆ 滑雪比赛 (BOBSLEDDING, 2009 DEC) |
将时间排序,每个弯角考虑:前一弯的速度,自己的限速,和后面“刹不住”,递推时顺便算答案 |
|
第9题 |
★☆☆☆☆ 自私的奶牛 (SELFISH GRAZING, 2009 DEC) |
经典的任务调度问题,按结束时间排序即可 |
|
第10题 |
★★☆☆☆ 重排干草 (HAYBALE RESTACKING, 2012 MAR) |
代数分析然后取中位数 |
同Uva 11300 BZOJ 1045 |
第11题 |
★★★☆☆ 奶牛集体照 (COW PHOTOGRAPHY, 2011 DEC) |
如果一头牛在另一头牛前面,则它至多在另一头前面2次,以此排序 |
|
第12题 |
★★★★☆ 奶牛集会 (MOOFEST, 2004 OPEN) |
V和X都做排序,按V从大往小扫,用数据结构计算x比它小的和与比它大的和 |
|
第13题 |
★☆☆☆☆ 购买饲料 (BUYING FEED 2, 2010 JAN) |
以距离+价格为关键字排序 |
|
第14题 |
★★☆☆☆ 保护花朵 (PROTECTING THE FLOWERS, 2007 JAN) |
s/t的比值为关键字排序 |
|
第15题 |
★★★☆☆ 奶牛杂技 (COW ACROBATS, 2005 NOV) |
w+s为关键字排序 |
|
第16题 |
★★★★☆ 二道工序 (THE MILK QUEUE, 2006 OPEN) |
排序关键字 return a.a + b.b + max(a.a, b.b) < a.b + b.a + max(a.b, b.a); |
|
第17题 |
★☆☆☆☆ 括号序列 (BEST PARENTHESIS, 2011 FEB) |
根据题目定义,维护一个栈即可 |
旧版的翻译有问题,没有说要mod多少 |
第18题 |
★★☆☆☆ 向右看齐 (LOOK UP, 2009 MAR) |
倒序维护一个单调队列再正序输出 |
|
第19题 |
★★★☆☆ 雄伟的山峦 (MOUNTAIN MAJESTIES, 2002 OPEN) |
按起点排序并去除完全覆盖的部分,然后进行扫描,分成两个三角形相交和相离讨论。 |
题目描述没有提到长度单位,自己随便定一个单位好了 |
第20题 |
★☆☆☆☆ 建造道路 (BUILDING ROADS, 2007 DEC) |
Kruskal 把已经建好的用并查集合并并计算出大小,有更好的办法,Prim将连通边长设为0 |
|
第21题 |
★★☆☆☆ 奶牛打井 (WATERING HOLE, 2008 OCT) |
增加一个点,到每个节点的距离为打一口井的耗费,求mst |
|
第22题 |
★★★☆☆ 奶牛施工队 (EARTHQUAKE, 2001 OPEN) |
将成本除以V-1减去收益,转化为最大比例生成树 |
|
第23题 |
★★☆☆☆ 翻转棋 (FLIPTILE, 2007 OPEN) |
枚举第一行即可 |
最优解指翻转次数最小的解 |
第24题 |
★★★★☆ 电灯 (LIGHTS, 2009 NOV) |
每个灯开两次以上没有意义,就可以转化为中途相遇了 |
|
第25题 |
★★★★★ 宝藏图 (TREASURE, 2008 HOL) |
||
第26题 |
★★☆☆☆ 奶牛飞盘队 (COW FRISBEE TEAM, 2009 MAR) |
分剩余系的背包 |
|
第27题 |
★★★☆☆ 滑雪缆车 (SKI LIFT, 2006 MAR) |
设d[i]为i为终点的答案.直接转移是三次方级.维护最大斜率用等积式计算就是平方级的 |
|
第28题 |
★★★☆☆ 奶牛自行车队 (COW CYCLING, FEB 2002) |
不妨设每头牛依次做领队,d[i][j][k]为当前第i头牛,第i头牛剩余体力为j,已过圈数为k时的最小答案 |
|
第29题 |
★★★★☆ 打扫食槽 (CLEANING UP, 2009 MAR) |
d[i]<=i所以每个i只需考虑sqer(i)个决策,维护sqrt(i)个区间进行转移 |
|
第30题 |
★★★☆☆ 奶牛探险 (EXPEDITION, 2005 OPEN) |
没油时看以前经过的加油站里有最多的加,用优先队列维护,注意先计算后进队 |
|
第31题 |
★★★☆☆ 赞助学费 (FINANCIAL AID, 2004 MAR) |
按成绩排序,枚举中位数,两侧各取n/2个最小奖金,用堆进行预处理 |
|
第32题 |
★★★★☆ 奶牛优惠券 (COW COUPONS, 2012 FEB) |
将p-c值存进小根堆,对于物品i,可以选择p[i]或c[i]+堆顶元素 |
|
第33题 |
★★★☆☆ 都市地平线 (CITY HORIZON, 2007 OPEN) |
将事件按时间排序,扫描并维护优先队列 |
|
第34题 |
★★☆☆☆ 象棋皇后 (CHECKER CHALLENGE, 1993 QUALIFYING ROUND) |
枚举即可,注意两条对角线和竖线的剪枝 |
|
第35题 |
★★☆☆☆ 拼图游戏 (JIGSAW PUZZLES, 2008 DEC) |
||
第36题 |
★★★☆☆ 埃及分数 (BABYLONIAN FRACTIONS, 1997 JAN) |
||
第37题 |
★★★★☆ 栅栏木料 (FENCE RAILS, 1999 SPRING) |
||
第38题 |
★★★★★ 解密牛语 (CRYPTCOWGRAPHY, 1998 WINTER) |
||
第39题 |
★★☆☆☆ 智取金币 (TREASURE CHEST, 2010 DEC) |
d[i][j]=a[i]+a[j]-min(d[i+1][j]+d[i][j-1]),但这样是二维的,用点长式可以化成一维空间 |
|
第40题 |
★★★☆☆ 最优回文 (CHEAPEST PALINDROME, 2007 OPEN) |
可以把添加操作转化为删除操作,从而变为经典的删数回文 |
|
第41题 |
★★★☆☆ 抢鲜草 (GRAZING ON THE RUN, 2005 NOV) |
设DP[l][r][s]为区间(l, r)的答案,s=0代表此时在l位置,s=1代表在r位置,可知在其他位置不划算 |
|
第42题 |
★★★★☆ 提交作业 (TURNING IN HOMEWORK, 2004 OPEN) |
||
第43题 |
★★☆☆☆ 拖拉机 (TRACTOR, 2012 MAR) |
维护两个队列BFS |
翻译有问题,n<=50000而且坐标可以是0 |
第44题 |
★★☆☆☆ 玉米迷宫 (CORN MAZE, 2011 OPEN) |
BFS,注意拓展节点时要记传送后的节点 |
题意不清,传送时传送且只传送1次,中间点不算经过 |
第45题 |
★★★☆☆ 奶牛攀岩 (THE CLIMBING WALL, 2006 OPEN) |
暴力建边会超时,可以按y坐标排序,加边的时候判定y坐标是否差1000以下,节省建边时间 |
"直线距离"指欧几里德距离,第4行"两块直线距离小于1000"应该是"不大于" |
第46题 |
★★★★★ 黄金莲花池 (LILYPAD POND, 2007 FEB) |
||
第47题 |
★★☆☆☆ 平分子集 (SUBSET SUMS, 1998 SPRING) |
背包问题,注意答案可能是0可能是long long |
|
第48题 |
★★★☆☆ 太空电梯 (SPACE ELEVATOR, 2005 MAR) |
按限高排序,再拆物品直接背包,用多重背包的算法更好 |
|
第49题 |
★★★☆☆ 奶牛会展 (COW EXHIBITION, 2003 FALL) |
设d[i][x]为前i头牛的子集智商和为x时情商和的最大值,用滚动数组和平移下标实现 |
|
第50题 |
★★★★☆ 股票市场 (STOCK MARKET, 2009 FEB) |
将买卖操作分解,从而最大化每天的利益,转化为完全背包 |
|
第51题 |
★★☆☆☆ 数数的梦 (DREAM COUNTING, 2006 DEC) |
数位dp,由于数据弱,高效的模拟也能过 |
|
第52题 |
★★★☆☆ 二进制编号 (COW QUEUEING, 2003 DEC) |
||
第53题 |
★★★☆☆ 开篇第一 (FIRST!, 2012 DEC) |
||
第54题 |
★★☆☆☆ 时间旅行 (TIME TRAVEL, 2010 OPEN) |
||
第55题 |
★★★☆☆ 真假奶牛 (LIARS AND TRUTH TELLERS, 2013 JAN) |
T代表两头牛属于同一帮派(都说实话或都说谎),用带权并查集实现 |
|
第56题 |
★★★☆☆ 工作安排 (WORK SCHEDULING, 2009 OPEN) |
按截止时间从晚到早选择最大收益的工作,用堆维护 |
|
第57题 |
★★★★☆ 导航难题 (NAVIGATION NIGHTMARE, 2004 FEB) |
||
第58题 |
★★★★☆ 叠积木 (CUBE STACKING, 2004 OPEN) |
||
第59题 |
★★★☆☆ 奶牛观光 (SIGHTSEEING COWS, 2007 DEC) |
二分判断负环 |
|
第60题 |
★★★☆☆ 领取巧克力 (CHOCOLATE GIVING, 2010 FEB) |
求一次SSSP即可,写的时候把优先级写反了 |
|
第61题 |
★★★★☆ 道路翻新 (REVAMPING TRAILS, 2009 FEB) |
建模,对于边(u,v) (u,k)向(v,k+1)连一条长为0的边,(u,k)向(v,k)连原长度的边,求一次SSSP |
|
第62题 |
★★★★★ 公路和航线 (ROADS AND PLANES, 2011 JAN) |
||
第63题 |
★★☆☆☆ 奶牛比赛 (COW CONTEST, 2008 JAN) |
对于一个点只需计算和他联通的点数,再转置计算一次,可以直接搜 |
|
第64题 |
★★☆☆☆ 奶牛跨栏 (COW HURDLES, USACO 2007 NOV) |
d[i][j]为i出发到j的答案,转移即可 |
|
第65题 |
★★★☆☆ 过路费 (COW TOLL PATHS, 2009 DEC) |
先将点权排序,floyd时只有i, j, k可能是点权最大的点,就能转移了 |
|
第66题 |
★★★★☆ 奶牛接力 (COW RELAYS, 2007 NOV) |
||
第67题 |
★★★☆☆ 录制唱片 (RAUCOUS ROCKERS, 1996 QUALIFYING ROUND) |
||
第68题 |
★★★★☆ 三个代表 (JERSEY POLITICS, 2005 FEB) |
||
第69题 |
★★★★☆ 电子游戏 (VIDEO GAME TROUBLES, 2009 DEC) |
输入格式的第二行莫名其妙多了几个字 |
|
第70题 |
★★★★☆ 最少找零 (THE FEWEST COINS, 2006 DEC) |
||
第71题 |
★★★☆☆ 手机网络 (CELL PHONE NETWORK, 2008 JAN) |
从下往上,f(i)为覆盖到,g(i)为覆盖到且该点有基站 |
|
第72题 |
★★★☆☆ 道路重建 (REBUILDING ROADS, FEB 2002) |
可以看做分组背包问题,d[i][j]为以i为根分离出j个点孤立的最小花费。注意最后枚举每个点作为根更新答案。 |
|
第73题 |
★★★★☆ 产奶比赛 (MILK TEAM SELECT, 2006 MAR) |
||
第74题 |
★★★★★ 焊接 (SOLDERING, 2011 OPEN) |
||
第75题 |
★★☆☆☆ 奶牛守卫 (WATCHCOW, 2005 JAN) |
很多边的欧拉回路,以边是否访问为状态DFS |
|
第76题 |
★★★★☆ 明星奶牛 (POPULAR COWS, 2003 FALL) |
缩点,拓扑序最低的点才可能是答案 |
同BZOJ 1051 |
第77题 |
★★★★☆ 两条路径 (REDUNDANT PATHS, 2006 JAN) |
双联通分量缩点,DAG度为1的点除以2取上整就是答案.注意整张图双连通时答案为0 |
|
第78题 |
★★★☆☆ 修剪草坪 (MOWING THE LAWN, 2011 OPEN) |
标准的单调队列优化 |
|
第79题 |
★★★☆☆ 玉米实验 (CORNFIELDS, 2003 MAR) |
二维RMQ,也可以用单调队列预处理 |
|
第80题 |
★★★★☆ 又买饲料 (BUYING FEED, 2010 NOV) |
输入格式“第二行到第K+1行” |
|
第81题 |
★★★★☆ 干草塔 (TOWER OF HAY, 2009 OPEN) |
||
第82题 |
★★★★☆ 土地并购 (LAND ACQUISITION, 2008 MAR) |
按h升序再按w升序排序,去掉能被完全覆盖的土地,这样h就单调增,w单调减,转换成标准斜率优化 |
|
第83题 |
★★★☆☆ 奶牛抗议 (GENERIC COW PROTESTS, 2011 FEB) |
DP方程式显然,用BIT优化即可,注意将sum数组离散化会方便不少,也不会爆内存 |
|
第84题 |
★★★☆☆ 奶牛赛跑 (RUNNING LAPS, 2012 OPEN) |
平方算法显然,nlogn可以把每头牛的时间分成整数部分和小数部分,整数部分求和小数部分求逆序数对 |
|
第85题 |
★★★★☆ 道路植草 (GRASS PLANTING, 2011 DEC) |
||
第86题 |
★★★★☆ 懒惰奶牛 (LAZY COWS, 2005 OPEN) |
||
第87题 |
★★★★☆ 洞穴奶牛 (CAVE COW 1, 2004 OPEN) |
||
第88题 |
★★★★☆ 安排牧场 (CORN FIELDS, 2006 NOV) |
||
第89题 |
★★★★☆ 奶牛猜数 (HAYBALE GUESSING, 2008 JAN) |
二分答案.将A值降序枚举,对于相同的A值集合取交集和并集,交集中必须要有空点.并集区间修改,可以离散化或并查集加速 |
|
第90题 |
★★★★☆ 跨栏训练 (FENCE OBSTACLE COURSE, 2004 DEC) |
||
第91题 |
★★★★☆ 预定旅馆 (HOTEL, 2008 FEB) |
对于一段区间,k连续区间只可能出现在左半、左半+右半、右半三种可能,用线段树维护,类似最大连续和 |
|
第92题 |
★★★★★ 修路 (CONNECT, 2007 OPEN) |
||
第93题 |
★★★★☆ 挑剔的美食家 (GOURMET GRAZERS, 2007 DEC) |
||
第94题 |
★★★★☆ 约翰的书架 (BOOKSHELF, 2012 OPEN) |
||
第95题 |
★★★★★ 期末总评 (COW SCHOOL, 2007 JAN) |
||
第96题 |
★★★☆☆ 奶牛晚宴 (DINING, 2007 OPEN) |
把每头牛拆成2头牛,连长度为1的边,把食物和要吃它的奶牛连接,饮料类似,加一个起点一个终点,用DFS的最大流就能过 |
|
第97题 |
★★★☆☆ 地震破坏 (EARTHQUAKE DAMAGE 2, 2009 MAR) |
拆点最小割,将节点u拆成u,u' u'向u连一条容量为1的边,图中其他边将容量设为INF,报告的点向超级汇点连容量是INF的边 |
|
第98题 |
★★★★☆ 小行星群 (ASTEROIDS, 2006 NOV) |
以行和列作为二分图的点,一个位置作为二分图的边,要求最小点覆盖,数值上等于最大匹配 |
来源应该是05NOV,同Uva 11419 |
第99题 |
★★★★★ 玩具消毒 (TOYS, 2008 NOV) |
同BZOJ 1221 |
然后是一些题目的题解
第3题,丑数 Humble
http://blog.csdn.net/qyl916/article/details/18894047
第6题,方形牛棚 bigbrn 第8题 滑雪比赛 bobsled
第10题 重排干草 Restack 第11题 奶牛集体照 photo
http://blog.csdn.net/qyl916/article/details/18894529
第15题 奶牛杂技 acrobat 第16题 两道工序 mqueue
http://blog.csdn.net/qyl916/article/details/18948601
第20题 建造道路 roads
典型的MST,只是Kruskal之前要把已经合并的边合并了,并计算事先多少个点已经联通
注意并查集的合并是把代表元素进行赋值
const int maxn=1010,maxm=1000010;
int n,m,x[maxn],y[maxn],fa[maxn],u[2*maxm],v[2*maxm],len,p[2*maxm];
double w[2*maxm];
int cmp(int x0,int y0){
return w[x0]=n-1)break;
++st;
//write1(st);
}
printf("%.2f\n",ans);
}
int main()
{
setio("roads");
len=0;
read2(n,m);
REP1(i,n)read2(x[i],y[i]);
REP1(i,n)REP1(j,n){
u[len]=i;v[len]=j;
w[len]=sqrt( ( (double)x[i]-x[j] )*( (double)x[i]-x[j] ) +( (double)y[i]-y[j])*((double)y[i]-y[j])); len++;
}
//REP(i,2*n*n)printf("%d %d %d %f\n",i,u[i],v[i],w[i]);
kruskal();
//system("pause");
return 0;
}
但这题用Kruskal是很糟糕的,用Prim把边长设为0更好。
const int maxn = 1010;
int x[maxn], y[maxn];
double g[maxn][maxn], minv[maxn];
int n, m, used[maxn];
double prim(){
rep1(i, n) minv[i] = INF; CLR(used, 0); minv[1] = 0;
double ans = 0;
while(1){
int u = -1;
rep1(i, n) if (!used[i] && (u==-1 || minv[u] > minv[i]) ) u = i;
if (u == -1) break;
ans += minv[u];
used[u] = 1;
rep1(i, n) minv[i] =min (minv[i], g[u][i]);
}
return ans;
}
int main()
{
scanf("%d%d", &n, &m);
rep1(i, n) scanf("%d%d", &x[i], &y[i]);
rep1(i, n) rep1(j, n) g[i][j] = sqrt( .0 + (double)(x[i] - x[j]) * (x[i] - x[j])
+ (double)( y[i] - y[j] ) *( y[i] - y[j]) );
//rep1(i, n) printf("%d %d\n", x[i], y[i]);
rep(i, m) {
int u, v;
scanf("%d%d", &u, &v);
g[u][v] = g[v][u] = 0;
}
//rep1(i, n) {rep1(j, n) printf("%.2f ", g[i][j]); PN;}
double ans = prim();
printf("%.2f\n", ans);
//while(1);
return 0;
}
第39题 智取金币 treasure
这题是明显的区间DP,方程式并不难写,但5000*5000的数组会爆USACO的16MB内存,所以需要简化。
这里有一个很经典的技巧,区间DP的计算顺序是按区间从短到长顺序的。所以可以换一种方程式的写法。
原来是d(l, r) 现在以左指针和区间长度来定义。原来的d(l, r)变成了d(l, r-l+1) 也称点长式。
这样的转移方式就能用滚动数组优化空间了。
换新的编译器就TLE了
似乎只是常数问题
改成递推,快了4倍
AC
bzoj上有MLE的问题
改成滚动数组
*/
void setio(string name){
string in_f=name+".in";
string out_f=name+".out";
freopen(in_f.c_str(),"r",stdin);
freopen(out_f.c_str(),"w",stdout);
}
int c[5010],s[5010],d[5010];
int main()
{
//setio("treasure");
int n;read(n);
REP1(i,n)read(c[i]);
s[0]=0;
REP1(i,n)s[i]=s[i-1]+c[i];
REP1(i,n)d[i]=c[i];
REP1(l,n-1)
REP1(i,n-l)
d[i]=s[i+l]-s[i-1]-min(d[i+1],d[i]);
writeln(d[1]);
//system("pause");
return 0;
}
第40题 最优回文 cheappal
拿到这题没想法,只能删除的话是容易的DP,但加插入就完全没法转移了。
其实删除操作等价于在另一端插入,插入操作等价于在另一侧删除,这样就能转化成标准的区间DP了。
int cost[200], d[2010][2010], n, m;
char s[2010];
int dp(int l, int r){
int &ans = d[l][r];
if (ans != -1) return ans;
if (l >= r) {ans = 0; return ans;}
ans = 0;
if (s[l] == s[r]) ans = dp(l + 1, r - 1);
else ans = min( dp(l, r - 1) + cost[s[r]], dp(l + 1, r) + cost[s[l]] );
return ans;
}
int main()
{
scanf("%d%d", &n, &m);
scanf("%s", s);
rep(i, n){
char c;int c1, c2;
scanf(" %c%d%d", &c, &c1, &c2);
cost[c] = min(c1, c2);
}
CLR(d, -1);
printf("%d\n", dp(0, m - 1) ); //while(1);
return 0;
}