hdu多校(三)1004 Tokitsukaze and Multiple(easydp)

1004 Tokitsukaze and Multiple

题意:给定序列 a n a_n an,数字 p p p。需要把数列分段,问段内和是p的倍数的最大个数。
思路:题意就已经换了一下了,原题这样:
在这里插入图片描述
问题就转换成了数列分段,有dp味道了。因为题目要求连续。8错8错,前缀和来了。

  • 用dp记录当前位置 i i i的最大个数,问题就在从啥状态转移来?好像可以随便转移,但是有贡献的位置 j j j必然是 ∑ k = j i a i % p = 0 \sum_{k=j}^i a_i\%p=0 k=jiai%p=0的地方。
  • 现在剩下的问题就是要找这个位置 j j j,利用前缀数组 % p \%p %p s u m sum sum记录,如果发现当前位置 s u m i sum_i sumi存在了一些位置相等,说明从这些位置转移来的 d p + + dp++ dp++.
  • 当然,如果不存在以上的位置就直接 d p i = d p i − 1 dp_i=dp_{i-1} dpi=dpi1就好

上号!

int n;
LL a[maxn], sum[maxn], dp[maxn];
int mp[maxn];
int main() {
	int T;
	int n;
	LL p;
	sci(T);
	while (T--)
	{

		sum[0] = 0;
		dp[0] = 0;
		sci(n); scl(p);
		for (int i = 0; i <= p; i++)mp[i] = -1;
		mp[0] = 0;
		for (int i = 1; i <= n; i++) {
			scl(a[i]);
			sum[i] = (a[i] + sum[i - 1]) % p;
			if (mp[sum[i]] != -1)dp[i] = max(dp[i-1], dp[mp[sum[i]]] + 1);
			else dp[i] = dp[i - 1];
			mp[sum[i]] = i;
		}
		cout << dp[n] << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值