HDU 4427 Math Magic

本文介绍了一种使用三维动态规划解决特定问题的方法,并通过滚动数组优化空间复杂度。通过预处理最小公倍数和枚举约数进一步提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示的是 前 iii个数,总和为 jjj ,LCM 为 kkk 的时候的种类数。

如果现在已知dp[i][j][k]dp[i][j][k]dp[i][j][k],那么我们可以求得下一个状态:

设下一个数为 sss ,那么 dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]] 状态可以由 dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]] 转移过来,故 dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]] 加上 dp[i][j][k]dp[i][j][k]dp[i][j][k] 的值即可。

那么此题需要空间优化以及时间剪枝优化。

由于操作的是三维数组上下两层,故可以用滚动数组优化空间复杂度。

再一点的是:
对于 dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]] 。这个是由 dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]]dp[i+1][j+s][lcm[k,s]] 转移过来的,那么一定要满足以下条件:

1、j+s&lt;=n(n为总和)1、j + s &lt;= n (n 为总和)1j+s<=nn

2、lcm[k,s]&lt;=m(m为所有数的lcm)2、lcm[k,s] &lt;= m(m为 所有数的lcm)2lcm[k,s]<=mmlcm

对于上面第二条我们得知: kkksss 一定是 mmm 的约数,因为它们的最小公倍数是 mmm

故预处理出 mmm 的所有约数,然后枚举 k和sk 和 sks 的时候,时间复杂度就会少许多。

然后就是还要预处理一下,在1000范围内的数,所有数的最小公倍数,因为之后 dpdpdp 会用到。

代码如下:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int lcm[1008][1008];
int dp[2][1008][1008];
int fac[1008];
int n, m, k, cnt;
const int mod = (int)(1e9 + 7);
int gcd(int a, int b)
{
	if (b)
		return gcd(b, a%b);
	return a;
}
int main()
{
	for (int i = 1; i <= 1000; i++) {
		for (int j = i; j <= 1000; j++) {
			lcm[i][j] = lcm[j][i] = (i * j) / gcd(i, j);
		}
	}
	while (~scanf("%d%d%d", &n, &m, &k))
	{
		cnt = 0;
		for (int i = 1; i <= m; i++) {
			if (m%i == 0) fac[++cnt] = i;
		}
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= cnt; i++) {
			dp[0][fac[i]][fac[i]] = 1;
		}
		int g = 0, t, tt, l;
		for (int i = 1; i < k; i++) {
			memset(dp[g ^ 1], 0, sizeof(dp[g ^ 1]));
			for (int j = i; j < n; j++) {
				for (int w = 1; w <= cnt; w++) {
					 t = fac[w];
					if (j + t > n) break;
					for (int q = 1; q <= cnt; q++) {
						 tt = fac[q];
						 if (!dp[g][j][tt]) continue;
						 l = lcm[t][tt];
						 if (l > m) continue;
						 dp[g ^ 1][j + t][l] += dp[g][j][tt];
						 dp[g ^ 1][j+t][l] %= mod;
					}
				}
				/*for (int w = 1; w <= cnt; w++) {
					 int t = fac[w];
					 if (!dp[g][j][t]) continue;
					 for (int q = 1; q <= cnt; q++) {
						 int tt = j + fac[q];
						 if (tt > n) break;
						int l = lcm[t][fac[q]];
						 dp[g ^ 1][tt][l] += dp[g][j][t];
						 dp[g ^ 1][tt][l] %= mod;
					}
				}*/
			}
			g ^= 1;
		}
		printf("%d\n", dp[g][n][m]);
	}
}
资源下载链接为: https://pan.quark.cn/s/9e7ef05254f8 在网页设计中,为图片添加文字是一种常见的需求,用于增强视觉效果或传达更多信息。本文将介绍两种常用的方法:一种是将图片设置为背景并添加文字;另一种是利用<span>标签结合CSS定位来实现。 这种方法通过CSS实现,将图片设置为一个容器(通常是<div>)的背景,然后在容器中添加文字。具体步骤如下: 创建一个包含文字的<div>元素: 使用CSS设置<div>的背景图片,并调整其尺寸以匹配图片大小: 如有需要,可使用background-position属性调整图片位置,确保文字显示在合适位置。这样,文字就会显示在图片之上。 另一种方法是将文字放在<span>标签内,并通过CSS绝对定位将其放置在图片上。步骤如下: 创建一个包含图片和<span>标签的<div>: 设置<div>为相对定位,以便内部元素可以相对于它进行绝对定位: 设置<span>为绝对定位,并通过调整top和left属性来确定文字在图片上的位置: 这种方法的优点是可以精确控制文字的位置,并且可以灵活调整文字的样式,如颜色和字体大小。 两种方法各有优势,可根据实际需求选择。在实际开发中,还可以结合JavaScript或jQuery动态添加文字,实现更复杂的交互效果。通过合理运用HTML和CSS,我们可以在图片上添加文字,创造出更具吸引力的视觉效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值