usaco3.1

3.1.1 agri_net

  赤裸裸的最小生成树,prim和kruskal算法都可以。

 

3.1.2 inflate

 dp,朴素的方法:

定义f[i][j]为剩余时间为i,考虑前j道题,的最大得分。

f[i][j]=max{f[i-t[j]][j-1]+p[j],f[i][j]}

其中f[i][0]都初始化为0 f[i][j]的默认比较值为f[i][j-1].

但是数据范围不够开2维数组,所以要用滚动数组来表示。

但是我得方程里面既有f[][j-1]又有f[][j],所以只好用f[][0]表示f[][j-1],f[][1]表示f[][j](2维滚动数组?)

当然,也可以把t[0] p[0]都存为0.

 

3.1.3 humb number

 这题开始百思不得其解,dfs,dp,都想过,貌似不好解。查解答,发现是用枚举法做的.不过这个枚举比较讲究技巧。

  假设我们已经得到了一些humb,从在这些humb中找出一个humb*prime[i](后面用h,p代替)就能得到新的h,但是我们还要保证这个h刚好是下一个,才能求得要求序列值的h。

  也就是说这个h是所有比当前最大hi值大的h的集合中最小的那个(这句话好拗口啊- -),现在问题清晰了,这是一个最大最小值问题。

  于是可以从最小的h开始不断用更大的p跟他乘,不能得到满足要求的就换一个更大的h重复上面步骤。

  这题的朴素解法就到这里了,光这样会超时,因为每次都从最小的h和p开始枚举有很多重复步骤。

  考虑到递增性,可以用这样的语句

while(prime[index[i]]*h[i]<hm)

     index[i]++;

它是对每个h得到一个index 使 prime[index]*h 能>hm, (如果这个h[i]很小,index就会增加到>prime的最大数目,之后就不会考虑这个h[i]了)。

 

3.1.4 shaping regions

  矩形切割,或者2维线段树(这个貌似比较复杂)。每次放新矩形上去后,就把覆盖处原来的矩形分成几个小部分,存入队列。 计算分开小矩形时先求左右2块再求上下2块,比较方便。

 

3.1.5contact *

  这题用位运算写很方便,其它办法可能超时。因为有前导0要考虑,可以在记录时增加维度或者直接在最高位添1。(通过这题才开始搞懂位运算,标个*号吧...囧)

 

3.1.6 stamps

  DP,因为要求能得到的 从1开始的连续集合的上限,第i个点能否加入集合的充要条件是 f[k][i-v[j]](j E S)中有一个为1(f[k][i]表示k枚邮票能否到达,s为所有邮票的集合)。(这是我自己的办法,倒数第3个点wa掉了,正确性受到质疑)

 还有个更好地办法,定义f[i]为到达i所需最小邮票数,连续枚举,若f[i]<=k,f[i+1]>=k,i就是所求了,可以用dp预先求出f[]。

 

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

你可能感兴趣的:(USACO)