7.13某中题解

1.分队问题

描述

给定n 个选手,将他们分成若干只队伍。其中第i 个选手要求自己所属的队
伍的人数大等于a[i]人。
在满足所有选手的要求的前提下,最大化队伍的总数。
注:每个选手属于且仅属于一支队伍。

输入格式

第一行一个整数 n,表示人数。 以下 n 行,每行一个整数表示 a[i]。

输出格式

输出队伍总数的最大值。数据保证有解。

数据范围

对于 20%的数据,n <= 10 对于 40%的数据,n <= 1000 对于 60%的数据,n <= 10000 对于 100%的数据,1 <= n <= 10^6

考试时想的是贪心,没想dp,没有读入优化。。。

正解:

将选手的 a [ i ] 从小到大排个序,然后dp:
状态: f [ i ] 表示前i名选手能构成的最多队伍数。
方程: f [ i ] = m a x f [ j ] + 1 其中 j <= i a [ i ]
然后用 m a x x [ j ] 提前计算前j个f的最大值即可。
时间复杂度: O ( n )

2.子矩阵

题目描述

小 A 有一个 N×M 的矩阵,矩阵中 1~N*M 这(N*M)个整数均出现过一次。 现在小 A 在这个矩阵内选择一个子矩阵,其权值等于这个子矩阵中的所有数的最 小值。小 A 想知道,如果他选择的子矩阵的权值为 i(1<=i<=N×M),那么他选择 的子矩阵可能有多少种?小 A 希望知道所有可能的 i 值对应的结果,但是这些结 果太多了,他算不了,因此他向你求助。

输入格式

第一行,两个整数 N,M。 接下来的 N 行,每行 M 个整数,表示矩阵中的元素。

输出格式

N×M 行,每行一个整数,其中第 i 行的整数表示如果小 A 选择的子矩阵权 值为 i,他选择的子矩阵的种类数。

数据范围

对于 30%的数据,1<=N,M<=50; 对于全部的数据,1<=N,M<=300。

考试时想的 O ( n 4 ) 暴力处理拿30分。

正解:

先用 O ( n 3 ) 处理出每个以i为矩阵上边,以j为下边,第k列的小子矩阵的最小值。
然后使用单调栈,将对于每个元素可以延伸的左右界求出即可。总共 O ( n 3 )
显然对于一个子矩阵的最小值,它会影响左边,右边比它大的元素延伸矩阵,就可以用单调栈了。

3.数字对

题目描述

对于一个数字对(a,b),我们可以通过一次操作将其变为新数字对(a+b,b)或(a, a+b)。 给定一正整数 n,问最少需要多少次操作可将数字对(1,1)变为一个数字对, 该数字对至少有一个数字为 n。

输入格式

第一行一个正整数 n

输出格式

一个整数表示答案。

数据范围

对于 30%的数据, 1<=n<=1000 对于 60%的数据, 1<=n<=20000 对于 100%的数据,1<=n<=10^6

考试时打表后迭代加深然后卡时才苟且通过。。。。太弱了。

正解:

显然从 1 1 递推到n肯定不可行,就考虑从n反推回去。
对于 x , y ,显然 x ! = y x , y >= 0 ,所以只有可能通过 x y , y 或者 x y x 其中一种情况推回 x , y ,而想到gcd过程就是辗转相除,即辗转相减,因此用gcd()模拟加速相减,就可算出(x,y)得到需要的次数。计算n与1至n-1的gcd()即可。时间复杂度: O ( n l o g 2 n )

反思与总结:

需要改进的:
T1:1.思考贪心算法时一定要证明自己的算法是正确的,或者努力推翻自己的算法,dp能用时就用dp;
2.数据大时要使用读入优化。
T2:1.要注意分析最小值的性质:即遇着最大值就不能再延伸,即用单调栈可以实现。
T3:1.要想涉及到数字的大部分都是数论,不要因为暴力苟且得分就不想数论了。

需要保持的:
T3:打表找规律,然后迭代加深,卡时倒推。考试暴力ac也是奇迹呀(既然想到倒退为啥还没想到gcd?还是对算法不够熟悉呀)

猜你喜欢

转载自blog.csdn.net/qq_42013837/article/details/81037615
今日推荐