【7.16】代码源 -【数组划分】【拆拆】【选数2】【最大公约数】

#665. 数组划分

题意:给定 n ( n ≤ 100 ) n(n\leq 100) n(n100) 个整数,将其划分为恰好 k ( k ≤ 100 ) k(k\leq 100) k(k100) 个子数组,求对每个子数组求和后按与运算的最大值。

题解:(动态规划) 代码源每日一题 Div1 数组划分

思路:刚开始我定义的是 d p ( i , j ) dp(i,j) dp(i,j) 为前 i i i 个元素分为 j j j 块的最大值,转移方程是 d p ( i , j ) = max ⁡ ( d p ( k , j − 1 ) & ( s u m ( k + 1 , i ) ) ) dp(i,j)=\max(dp(k,j-1)\&(sum(k+1,i))) dp(i,j)=max(dp(k,j1)&(sum(k+1,i))) ,但是这样是不行的。详细讲一下为什么不行。

首先,每个状态本质是集合,集合中每个元素对应的有权值,根据题目我们通常要求集合的权值上界或者下界(即通常所说的 max ⁡ − min ⁡ \max-\min maxmin ),即集合的属性。如果我们采用 DP 递推的方式求这种属性,就必须保证后继状态的属性与前驱状态的属性是单调的。怎么理解呢?

我们定义一个自变量 x x x ,他的定义域就是前驱节点的权值值域(当然是有上下界的)。我们根据递推方程,后继节点的权值值域 y = f ( x ) y=f(x) y=f(x) 。只有当 f ( x ) f(x) f(x) 在定义域内是递增的,才能通过维护前驱的上界(下界),来得到后继值域的上界(下界)。如果不满足单调递增,那么后继状态的极值不一定会在前驱状态的上界(下界)取得。动态规划的这个递推单调属性也很重要。

回到这题,因为是位运算,前驱节点的取值递增不一定使得后继节点的值递增,那么这个方法就不行了。

这道题的做法是:从高位开始枚举答案的二进制位,然后判断序列是否有分成 k 份的方案使得和的与大于等于 ans,然后做出是否保留该位 1 的决策。DP 存在性的话, y ≥ x y\geq x yx 的充要条件是 ( y & x ) = = x (y\&x)==x (y&x)==x ,如果存在分割方案的话,每一段都必须满足 s u m i & x = = x sum_i\&x==x sumi&x==x ,定义 d p ( i , j ) dp(i,j) dp(i,j) 表示前 i 个分成 k 份是否存在方案使得和的与大于等于 x,DP 转移存在性。

AC代码:http://oj.daimayuan.top/submission/290596


#611. 拆拆

题意:多组数据。每组给定两个数 X,Y,问有多少个长度为 Y 的整数序列之乘积为 X。 T ≤ 1 0 5 , X , Y ≤ 1 0 6 T\leq 10^5,X,Y\leq 10^6 T105,X,Y106

思路:拆分质因子然后分配即可。

拆分质因子的方法优化( O ( a ∼ b ) O(a\sim b) O(ab) 表示预处理时间为 a a a,查询时间为 b b b):

  1. 预处理得到所有质数,然后只用质数去筛,时间复杂度 O ( n ∼ n ln ⁡ n ) O(n\sim\frac{\sqrt n}{\ln{\sqrt n}}) O(nlnn n )
  2. 用埃氏筛预处理所有数,得到每个数的质因子(级数为 log ⁡ n \log n logn),时间复杂度为 O ( n × log ⁡ log ⁡ n ∼ log ⁡ n ) O(n\times \log \log n\sim \log n) O(n×loglognlogn)

这道题用的是第二个优化。我们把一个数的所有质因子预处理存起来,然后直接使用即可。

vector<int> primes[M];

for(int i = 2; i < M; i ++ ){
	if(primes[i].size()) continue;
	for(int j = i; j < M; j += i){
		int t = j, cnt = 0;
		while(t % i == 0) cnt ++ , t /= i;
		primes[j].push_back(cnt);
	}
}

AC代码:http://oj.daimayuan.top/submission/291303


#618. 选数2

题意:

在这里插入图片描述

题解:(贪心)代码源每日一题 Div1 选数2

思路:首先求出 m m m 。如果存在长度为 m m m 的子序列满足题意,那么必定存在长度为 m m m 的子区间满足题意,因为我们固定右端点,把其他数向右移,平均数只会变得更大。这样可以二分求出 m m m

求出 m m m 之后,我们对于每个满足题意的子串,都只让左端点向左移,这样可以保证左端点向左移的距离尽可能地远。仍然是二分。

AC代码:http://oj.daimayuan.top/submission/290739


#131. 最大公约数

题意:你有一个环,环上有 n n n 个正整数。你能将环切成段,每段包含一个或者多个数字。

对于一个切分方案,优美程度为每段数字和的最大公约数,你想使切分方案的优美程度最大,对于 k = 1 , 2 , ⋯   , n k=1,2,\cdots,n k=1,2,,n 输出答案。

题解:(数学/枚举/环上问题)代码源每日一题 Div1 最大公约数

思路:我们把环分为 k k k 份,那么 g c d ∣ s i , i ∈ [ 1 , k ] gcd|s_i,i\in [1,k] gcdsi,i[1,k] ,即 g c d ∣ ∑ i = 1 k s i = s u m gcd|\sum_{i=1}^k{s_i}=sum gcdi=1ksi=sum 。我们枚举 s u m sum sum 的因子即 g c d gcd gcd 。因子的数量级可以认为是期望 log ⁡ n \log n logn ,最坏 n \sqrt n n 的。

对于 g c d gcd gcd ,我们可以求出最多可以分割为多少个段,因为段可合并,后缀和最大即可。如果是普通序列,那么直接求前缀和中有多少个数在   m o d   g c d \bmod gcd modgcd 的意义下为 0 0 0 。如果是环的话,我们要求前缀和中有多少个数在   m o d   g c d \bmod gcd modgcd 的意义下相等

AC代码:http://oj.daimayuan.top/submission/290873

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值