CF1005D Polycarp and Div 3

本题标签是贪心、字符串和前缀和,但是最重要的是动态规划。

我们考虑设 fif_i 表示前 ii 个字符最多段数,很显然我们枚举 jj11ii,对于每个 [j,i][j,i] 求一次数字和,如果为 33 就对贡献加 11

但是很明显这个复杂度是 O(n2)O(n^2),妥妥 TLE。这时,数学就登场了。

我们知道任一自然数除以 33 余数可能为 0,1,20, 1, 2。从反面考虑,我们尽量让若干个数相加仍然不是 33 的倍数。明显,我们尽量让余数为 00 的不出现。那么 1+20(mod3)1+2 \equiv 0\pmod 31+1+12+2+20(mod3)1+1+1 \equiv 2+2+2 \equiv 0\pmod 3,可得,任取 33 个自然数,其中必有连续的若干个数的和是 33 的倍数。

因此,可以将 jj 的枚举范围变为 [i2,i][i-2, i],代码实现:

#include <string>
#include <iostream>
using namespace std;

#define int long long
const int N = 2e5 + 5;

int dp[N], pre[N], ans = 0;
string s;

signed main()
{
	cin >> s;
	int len = s.size(), ans = 0;
	for (int i = 1; i <= len; i++) pre[i] = pre[i - 1] + (s[i - 1] - '0');
	for (int i = 1; i <= len; i++)
	{
		for (int j = i; j >= i - 2; j--)
		{
			if (j < 1) break;
			int x = pre[i] - pre[j - 1];
			dp[i] = max(dp[i], dp[j - 1] + (x % 3 == 0 ? 1 : 0));
		}
		ans = max(ans, dp[i]);
	}
	cout << ans << endl;
	return 0;
}
posted @   HappyBobb  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示