Codeforces Round #162 (Div. 2) (完全)

本文分享了ACM竞赛中的三道题目解题思路:C题寻找规律而非模拟,D题利用公因数优化O(n^2)算法,E题采用动态规划并维护最大次大状态。

没留意比赛时间,赛后虚拟比赛做的

C题我很弱的又跳进坑里了。竟然在模拟,太失败了。


C

注意规模 10^6,也就是要把区间对半分10^6次,模拟虽然不会超时,用脑子想想,精度肯定吃不消, 太搓了。

所以这题要找一定的规律,其实规律很简单:

当你选择左边时,你会发现之后的石头的位置都在你选择之前落下来的石头的位置的左边,

当你选择右边时,你会发现之后的石头的位置都在你选择之前落下来的石头的位置的右边。

类似两个vector。

code


D

我们很容易想到用O(n^2)解决这题,但这无疑会超时,我们可以对这种方法进行优化,降低其复杂度,

O(n^2)的做法,当推到第i个时,我们找其中1-----i-1中满足条件的最大的+1赋值给i,我们可以降低这一步骤的复杂度,把一些不必要的情况给去掉。

题目给的序列已经是递增了,所以我们只要 满足每两个相邻数不互质就可以了, 每两个相邻数不互质说明它们必定有个公因数,我们在递推的过程中可以通过公因数这个桥梁实施递推。

当处理到i时,我们枚举i的所有公因数, 然后通过公因数找到 i之前并且离i最近的 公因数与其相等的数的下标,然后更新i的最值。

code


dp[i]表示以颜色i结尾的最大价值,前面更新i的状态的分为两种情况:

1.   颜色一样也是i,则 得一值x1 = dp[c[i]] + a*v[i];

2    颜色不一样,颜色为cc, 则得一值x2 = dp[c[i]] + b *v[i];

3   只选i, 得x3 = 0 + b* v[i];

取其中的最大值赋值为dp[i], 当然i之前取的状态必须是最大值。

即 dp[c[i]]为i之前以颜色c[i]结尾的最大值

dp[cc]为i之前以不同与c[i]的n-1个颜色中某种颜色结尾,且dp[cc] >= dp[cccc]  (cccc 为任意的颜色, 但 cccc != c[i])。

关键是状态2,3如何实现。

更新状态i之前,我们可以取c1,c2保存i之前dp[] 最大的两个颜色下标(最大,次大)。

由于,初始的时候c1,c2 赋值为0,表示没有颜色,此时dp[0] = 0(题目规定所选的序列可以为空,所以最大值一定大于等于0)。

因此状态3可以合并在状态1,2中。

所以状态2,3的转移必定是 c1,c2中的某一个。

所以我们只要维护c1,c2,然后能求出每个dp[i], 答案就是dp[c1]。

code



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值