首页 > 其他分享 >CF837D题解

CF837D题解

时间:2023-02-24 22:24:37浏览次数:32  
标签:状态 int 题解 个数 sum2 CF837D dp

CF837D题解

没有用的话

今天晚上在 CF 题库里随便选题选的,感觉还不错的题。

昨天就开始停自习了,但是一直在摆烂(悲,自从上个学期就这样了,非常怀念一年前的机房,风清气正,大家都在为打破弱校桎梏、取得前所未有的成绩的目标而努力学习,偶有摆烂,带来的只有深深的愧疚感和危险感(想到EZ、HZ的大佬就会觉得危险)

这题其实是我随便之中选的,从昨天开始我就在 CF 选一些 2000+ 左右的题水一水,其实打算做 pjudge 上之前 noip 的模拟赛的,但是由于摆烂没时间做了。

另外:洛谷的第一篇题解写的是真好(这不是废话)

思路

就是冲着 dp 的tag去的,所以第一开始就往 dp身上靠了。

考虑到是选出 \(k\) 个数,所以想到背包, 当前状态 $f_{i, j} $,前 \(i\) 个,选 \(j\) 个,乘积 0 最多个数。

这样好像不行……我们考虑添状态维度

DP进阶:堆维度和删维度就是了。——鲁迅

增加维数。

我们拿到一道题且无从下手时,其正解一般是DP。 为什么我们做不出来?因为其中有很多很多因变量不受我们控制。也就是说,我们在考虑该状态转移的过程中应该尽量多的选择具有后效性的状态,而后再想着怎么优化降维。 ---luogu题解

此言得之!

我们可以从题中找到一些关于状态转移的信息:如何对末尾的 0 有更多贡献?我们可以考虑分解质因数,发现只有 2 和 5 可以对末尾的 0 的个数产生影响,而选的数分解质因数中的所有 2 的个数和所有 5 的个数,他们两个的最小值其实就是末尾 0 的个数。

考虑设计状态 $f_{i, j, sum2, sum5} $,前 \(i\) 个数,选 \(j\) 个,其中质因数 2 有 \(sum2\) 个,5 有 \(sum5\) 个,是否可行。

然后……MLE了……

整体与部分的转化(即可行性转最优)。

我们在某题(BZOJ1079)可能会暴力出来一个1e9维的dp方程。不妨再想想:
可不可以把其中一个维度扔出来作为dp的含义呢?
很高兴的是,这道题就是那么优化的 ---luogu题解

设计状态 \(f_{i, j, sum2}\),表示 有 \(sum2\) 个2时5的个数,最后找 \(sum2\) 和 \(f_{n, k, sum2}\) 的最小值的最大值就行了。

状态转移就是背包的转移,不必多说。

Code

#include <bits/stdc++.h>
#define int long long
#define maxn 605
using namespace std;
inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}
int n, m, sum;
int f[2][maxn][maxn * 10], a[maxn];
int get(int x, int p) {
	int res = 0;
	while (x % p == 0) {
		res++;
		x /= p;
	}
	return res;
}
signed main() {
	n = read(), m = read();
	memset(f, -1, sizeof(f));
	f[0][0][0] = 0;
	for (int i = 1; i <= n; i++) {
		a[i] = read();
		int s2 = get(a[i], 2), s5 = get(a[i], 5);
		sum += s2;
		for (int j = 0; j <= min(m, i); j++) {
			for (int k = 0; k <= sum; k++) {
				f[i & 1][j][k] = max(f[i & 1][j][k], f[(i - 1) & 1][j][k]);
				if (j > 0 && k >= s2 && ~f[(i - 1) & 1][j - 1][k - s2])
					f[i & 1][j][k] = max(f[i & 1][j][k], f[(i - 1) & 1][j - 1][k - s2] + s5);
			}
		}
	}
	int ans = 0;
	for (int i = 0; i <= sum; i++) 
		ans = max(ans, min(i, f[n & 1][m][i]));
	cout << ans;	
	
}

标签:状态,int,题解,个数,sum2,CF837D,dp
From: https://www.cnblogs.com/djc01/p/17153367.html

相关文章

  • THUPC2019 令人难以忘记的题目名称 题解
    首先感性感觉这个东西是比较有循环节的,但这是后话。最后几步一定是差分相同->每个数相同->全为0。不平凡地猜想差分\(k\)次全\(0\)等价于可以\(k\)步胜利。假设......
  • Universial Cup 题解
    开始瞎做题了全部都写了简要题意,题解默认折叠,可以来做做(?UniversialCup官网The1stUniversalCup比赛名称&题解链接题解包含题目QOJlinkCodeforcesGymLin......
  • 题解 北大集训2018 点分治
    题意给定\(n\)个点的树,求点分治方案数,对\(10^9+7\)取模。两种方案不同当且仅当点分树不同。\(1\leqn\leq5000\)题解考虑怎样合并两个点分治方案。如果我们有......
  • history 题解(并查集)
    考虑使用边带权并查集维护点之间的连通性,边权为这条边建立的时间,查询时如果查询时间小于边权则不能通行(巧妙地处理了时间的性质)。由于时间这种东西性质特殊无法路径压缩,所......
  • 新版 Mac M2 安装老 saas 项目 报 Gem sass is not installed 问题解决
     换了新电脑,需要把老项目git拉下来再跑起来的时候发现生成样式文件的时候会报这个错误,(N年前老项目,用的是node-sass,[email protected]版本比较老旧,但项目还是要......
  • vue——更改路由模式为history后,刷新页面显示Cannot Get/空白/404,本地icon图标不显示
    参考:https://blog.csdn.net/william_jzy/article/details/106526339   https://www.bbsmax.com/A/A7zgKEVkz4/      https://router.vuejs.org/zh/gu......
  • CF1131B 题解
    题目传送门好水的绿题,当放松了。题目分析为了方便表述,定义\(lsta,lstb,nowa,nowb\),分别表示上次双方的得分以及当前的得分。考虑分讨,若\(lsta=lstb\),贡献即\(\min(n......
  • P6666 [清华集训2016] 数据交互 题解
    ##P6666[清华集训2016]数据交互题解###简要题意:n个点的树,m次操作,分别为添加一条路径$(u_i,v_i,w_i)$,和撤消一条路径,每一次操作后求出一条路径使得与这条路径有交的......
  • P8422 题解
    前言题目传送门!更好的阅读体验?第三道大模拟,写篇题解庆祝一下。文中粗体字是我踩坑的地方,欢迎统计我被坑了多少次。思路终局奖分很简单,放在主函数里,所以我们看每次的......
  • 树剖练习题题解总和(动态更新)
    这篇博客的练习题题解1、P3384【模板】轻重链剖分/树链剖分模板题,详见此#include<iostream>#include<cstdio>#include<vector>usingnamespacestd;intn,m,r,p,t[......