【Orz5】 2014.08.09集训总结

来源:互联网 发布:淘宝优化排名 编辑:程序博客网 时间:2024/06/03 17:37

Today is a nice day!

这几天做了几套题现在才来一一总结。

ORZ5 vijos模拟赛

由于之前做过这个系列的比赛冥冥中就有了一些规律 导致这次分数比较高。

 

比赛分数 100+100+100+0。

 

T1 最大配对

题目:给出2个序列A={a[1],a[2],…,a[n]},B={b[1],b[2],…,b[n]},从A、B中各选出k个元素进行一一配对(可以不按照原来在序列中的顺序),并使得所有配对元素差的绝对值之和最大。 
  例如各选出了a[p[1]],a[p[2]],……,a[p[k]]与b[q[1]],b[q[2]],……,b[q[k]],其中p序列中的元素两两不相同,q序列中的元素两两不相同,那么答案为|a[p[1]]-b[q[1]]|+|a[p[2]]-b[q[2]]|+……+|a[p[k]]-b[q[k]]|,现在任务也就是最大化这个答案

 

  和NOIP难度一样 第一题一般都不会太难 稍微注意一下别掉坑就好了。

  分析一下,易证每一个最佳配对必定是最大配最小,所以只要A , B排下序 依次从最大最小取配对就好了。

 

T2 旅行

 

题目:今天又是个神圣的日子,因为LHX教主又要进行一段长途旅行。但是教主毕竟是教主,他喜欢走自己的路,让别人目瞪口呆。为什么呢,因为这条路线高低不平,而且是相当的严重。 
  但是教主有自己的办法,他会魔法。 
  这段路可以用一个长度为n的序列A[i]来表示,A[i]表示了第i这段路的高度。毕竟教主即使会使用魔法他还是个人,教主如果想穿越这条路线,他必须从第1段路开始走,走到第n段,从第i段走到第i+1段路需要消耗|A[i+1]-A[i]|点体力。为了节省体力,教主使出了他另一种神奇的魔法。教主的魔法可以交换相邻两段路的高度,并且这种魔法不需要花费额外的体力。但是第二次使用魔法开始,交换的两段路在路线中的位置需位于之前交换的两段路之后。即如果某次交换了A[j]和A[j+1],那么下次交换A[k]和A[k+1]必须满足j<k。 
  接着,LHX教主想规划下如何调整路段高度后穿越,使得体力消耗最小。

 

题目已经很明显啦 对于这种交换的 一般都是DP那么怎么DP呢

 

我当时也想了很久,想着怎么正着DP【顺推】推了将近45MIN无果后我决定放弃。就当我决定做下一题的时候 发现T3比较水【于是就滚去T3】了。。。。

 

当我做完T3的时候受了T3的启发 不要顺着走 倒着走会怎么样?

充分证明:正难则反。

对于每一个点 要么就交换到后面 要么就不换 而且换完之后对前面的状态毫无影响。

设F[i][0] 表示i移动 I --> N的最小代价

   F[i][1]表示i不移动  I --> N的最小代价

 

暴力枚举J  表示I移动到J , 计算出这个状态下的值 取最小的就好了。

如何转移?对于I 来说,若是移动,I这个位置的值必定为A[I+1] , 且I移动到J时 I+1à J的相对位置是不变的 这样就可以推出DP方程

 

for (int i = n-2 ; i ; i--)     {        f[i][1] = min(f[i + 1][1] + abs(a[i] - a[i + 1]) , f[i + 1][0] + abs(a[i] - a[i + 2]));        int tmp = f[i][0];        for (int j = i+1 ; j < n ; j++)         {            int tx =sum[j] - sum[i + 1] + abs(a[j] - a[i]);            if (tx + f[j + 1][1] + abs(a[j + 1] - a[i]) < tmp )                tmp = tx + f[j + 1][1] + abs(a[j + 1] - a[i]);            if (tx + f[j + 1][0] + abs(a[j + 2] - a[i]) < tmp && j != n-1)               tmp = tx + f[j + 1][0] + abs(a[j + 2] - a[i]);        }        tmp = min (tmp , sum[n] - sum[i + 1] + abs(a[n] - a[i]));        f[i][0] = tmp;    }

 特殊处理一下 J = N – 1的值就完成了答案就是min(F[1,0],F[1,1])。

 

 

T3资源勘探

这题有两个版本 比赛时做了较简单版 我也就这么水过了。

题目:教主要带领一群Orzer到一个雄奇地方勘察资源。 
  这个地方可以用一个n×m的矩阵A[i, j]来描述,而教主所在的位置则是位于矩阵的第1行第1列。
  矩阵的每一个元素A[i, j]均为一个不超过n×m的正整数,描述了位于这个位置资源的类型为第A[i, j]类。教主准备选择一个子矩阵作为勘察的范围,矩阵的左上角即为教主所在的(1, 1)。若某类资源k在教主勘察的范围内恰好出现一次。或者说若教主选择了(x, y)即第x行第y列作为子矩阵的右下角,那么在这个子矩阵中只有一个A[i, j](1≤i≤x,1≤j≤y)满足A[i, j]=k,那么第k类资源则被教主认为是稀有资源。 
  现在问题是,对于所有的(x, y),询问若(x, y)作为子矩阵的右下角,会有多少类不同的资源被教主认为是稀有资源。

 

Input

  输入的第一行包括两个正整数nm,接下来n行,每行m个数字,描述了A[i, j]这个矩阵。

Output

为了照顾Vijos脑残的输出问题,设B[i, j]表示仅包含前i行与前j列的子矩阵有多少个数字恰好出现一次,那么你所要输出所有B[i, j]之和mod 19900907

转折就在output

对于单独的X,Y 我除了暴力做我想不到其他的了。

但是题目说了 计算所有的B[I,J], 这就有机可乘:我们不考虑单独的X,Y,而是考虑每种资源对总答案的影响。

 

对于同一行同一种资源 ,第一出现的位置和第二次出现的位置之间即为被当做稀有资源的位置。若是只有一行,直接找最小列号和次小列号就可以了。

 

对于多行一样的 每次只要维护所出现过的最小和次小列号就可以了。

 

 

 

T4:排列统计

题目:对于给定的一个长度为n的序列{B[n]},问有多少个序列{A[n]}对于所有的i满足:A[1]A[i]i个数字中有恰好B[i]个数字小等于i。其中{A[n]}1n的一个排列,即1nn个数字在序列A[I]中恰好出现一次。 
  数据保证了至少有一个排列满足B序列。

 

题目大意如题。。。

比赛的时候我是连暴力都没想出来的 更别提好方法了 在保证前三题没问题的情况下我才看第四题【约莫只剩一个小时】到现在为止我还是不会暴力 看了题解就直接上正解了。

传送门àhttp://hi.baidu.com/qyjubriskxp/item/318f961166a07c12e3f98600

 

以下是题目的传送门:vijosP1660 – 1663

https://www.vijos.org/p/1660

https://www.vijos.org/p/1661

https://www.vijos.org/p/1662

https://www.vijos.org/p/1663

真丶资源勘探:https://www.vijos.org/p/1664有兴趣的同学可以去看看

 

 

0 0
原创粉丝点击