[UVA12063] Zeros and Ones && 数位DP

本文介绍了一个使用枚举法解决特定计数问题的C++程序实例。通过递归动态规划的方式,该算法能够高效地计算出在给定长度和模条件下,满足特定条件的序列数量。

枚举1的个数就行了.....

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 70;
const int MAXK = 100;
LL d[MAXN+10][MAXN * 2 + 10][MAXK+10], mod[MAXN+10];
LL n, K;
LL dp(int cur, int O, int MOD)
{
	if(cur == 0) {
		if(O) return 0;
		return d[cur][O][MOD] = ((MOD % K == 0) ? 1 : 0);
	}
	if(d[cur][O][MOD] != -1) return d[cur][O][MOD];
	LL &ans = d[cur][O][MOD];
	
	ans = dp(cur-1, O, MOD);
	if(O > 0) ans += dp(cur-1, O-1, (MOD - mod[cur] + K) % K);
	return ans;
}
void init()
{
	mod[1] = 1;
	for(int i = 2; i <= MAXN; i++) mod[i] = (mod[i-1] << 1) % K;
}
int main()
{
	int T, kase = 1; for(SF("%d", &T); kase <= T; kase++) {
		memset(d, -1, sizeof(d));
		cin >> n >> K;
		PF("Case %d: ", kase);
		if(K == 0 || (n & 1)) { cout << 0 << '\n'; continue; }
		init();
		LL ans = dp(n-1, (n-1) / 2, (K - mod[n]) % K);
		cout << ans << '\n';
	}
}


<think> 我们正在讨论`np.zeros`和`np.ones`函数在使用不同参数形式时(类似于`np.array([5,5])`、`np.array(5)`、`np.array((5,5))`)的行为是否与`np.array`有相同的区别。 回顾`np.array`的行为: 1. `np.array([5,5])`:输入列表,创建一维数组,形状为(2,) 2. `np.array(5)`:输入标量,创建零维数组(标量数组),形状为() 3. `np.array((5,5))`:输入元组,创建一维数组,形状为(2,) 现在,我们来看`np.zeros`和`np.ones`的用法。根据引用[1]和引用[3]: - 这两个函数的主要参数是`shape`,它可以是整数或整数元组,用于指定数组的维度。 - 它们也有`dtype`参数来指定数据类型。 因此,`np.zeros`和`np.ones`的参数是形状(shape),而不是像`np.array`那样直接传入数据。所以,我们不能直接传入类似`[5,5]`或`(5,5)`这样的数据,而是需要传入表示形状的参数。 例如: 1. 创建一个形状为(2,)的一维数组(类似于`np.array([5,5])`产生的形状): ```python np.zeros((2,)) # 或 np.zeros(2) np.ones((2,)) ``` 2. 创建一个零维数组(标量数组)(类似于`np.array(5)`产生的形状): ```python np.zeros(()) # 注意:这里传入一个空元组表示零维 np.ones(()) ``` 但是,注意:我们通常不会这样用,因为零维数组在实际中较少使用。另外,传入整数5表示形状为(5,)的一维数组,而不是零维数组。 3. 创建一个形状为(2,)的一维数组(类似于`np.array((5,5))`): ```python np.zeros((2,)) # 或者 np.zeros(2) np.ones((2,)) ``` 因此,对于`np.zeros`和`np.ones`,输入参数是形状(shape),所以: - 当我们想创建一个一维数组(长度为2)时,我们可以用整数2(会被解释为(2,))或者元组(2,)。 - 当我们想创建一个零维数组时,必须使用空元组`()`作为形状。 注意:`np.zeros(5)`和`np.zeros((5,))`是等价的,都创建一个长度为5的一维数组。而`np.zeros((5,5))`则创建一个5x5的二维数组。 那么,与`np.array`的区别在于: - `np.array`的输入是数据,而`np.zeros`和`np.ones`的输入是形状(即维度信息),并且它们会用0或1填充。 - 在`np.array`中,我们通过输入的数据结构(标量、列表、元组)来推断数组的维度;而在`np.zeros`和`np.ones`中,我们直接指定维度。 总结: | 函数 | 参数示例 | 结果数组形状 | 说明 | |---------------|----------------|--------------|----------------------------------------------------------------------| | `np.array` | `[5,5]` | `(2,)` | 从列表创建一维数组 | | | `5` | `()` | 从标量创建零维数组 | | | `(5,5)` | `(2,)` | 从元组创建一维数组(元组被解释为两个元素的一维结构) | | `np.zeros` | `2` 或 `(2,)` | `(2,)` | 创建形状为(2,)的一维零数组 | | | `()` | `()` | 创建零维零数组(标量数组) | | | `(2)` | `(2,)` | 注意:`(2)`在Python中就是整数2(因为元组只有一个元素时必须有逗号,否则就是整数),所以`(2)`等价于`2`,即形状(2,) | | | `(5,5)` | `(5,5)` | 创建5x5的二维零数组 | | `np.ones` | 同上 | 同上 | 同上,但填充1 | 注意:对于`np.zeros`和`np.ones`,如果传入一个整数n,它会被解释为一个一维数组的形状(n,)。如果要创建零维数组,必须传入空元组`()`。 所以,它们之间的区别在于参数的含义不同。`np.array`的参数是数据,而`np.zeros`和`np.ones`的参数是形状。 下面用代码示例说明: ```python import numpy as np # 使用np.array arr1 = np.array([5,5]) # 一维数组,形状(2,) arr2 = np.array(5) # 零维数组,形状() arr3 = np.array((5,5)) # 一维数组,形状(2,) # 使用np.zeros zeros1 = np.zeros(2) # 一维数组,形状(2,),元素为0.0 zeros2 = np.zeros(()) # 零维数组,形状(),元素为0.0 zeros3 = np.zeros((2,)) # 同zeros1 zeros4 = np.zeros((5,5)) # 二维数组,形状(5,5) # 使用np.ones ones1 = np.ones(2) # 一维数组,形状(2,),元素为1.0 ones2 = np.ones(()) # 零维数组,形状(),元素为1.0 ones3 = np.ones((2,)) # 同ones1 ones4 = np.ones((5,5)) # 二维数组,形状(5,5) ``` 因此,在`np.zeros`和`np.ones`中,我们通过传入的形状参数来控制数组的维度,这与`np.array`通过输入数据推断维度的方式不同。但是,我们可以通过指定形状参数来模拟`np.array`的维度效果。 另外,需要注意的是,在`np.zeros`和`np.ones`中,如果我们传入一个整数(如5),它表示一维数组(长度为5),而不是零维数组。零维数组必须通过空元组`()`来创建。 结论:虽然`np.zeros`和`np.ones`的参数形式(整数、元组)与`np.array`的数据输入形式在语法上类似,但它们的含义不同。因此,我们不能直接认为`np.zeros(5)`对应`np.array(5)`(实际上,`np.zeros(5)`创建一维数组,而`np.array(5)`创建零维数组)。相反,`np.zeros(())`才对应`np.array(5)`的维度(零维),但元素是0而不是5。 最后,回答用户的问题:`np.zeros`和`np.ones`在使用不同参数形式时,其行为与`np.array`不同,因为参数的含义不同(形状 vs 数据)。但是,我们可以通过指定特定的形状参数来创建与`np.array`相同维度的数组。 </think>### `np.zeros` 和 `np.ones` 不同参数形式与 `np.array` 的区别分析 #### 1. **`np.zeros([5,5])` vs `np.array([5,5])`** - **`np.zeros([5,5])`**: - 输入为列表 `[5,5]` 时,NumPy 将其解释为 **形状参数** - 创建 **二维零数组**:5×5 的矩阵 - 示例: ```python >>> np.zeros([5,5]) array([[0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.]]) ``` - 形状:`(5, 5)`[^1][^3] - **`np.array([5,5])`**: - 输入为列表 `[5,5]` 时,NumPy 将其解释为 **数据内容** - 创建 **一维数组**:包含元素 `[5, 5]` - 形状:`(2,)`[^2][^4] #### 2. **`np.zeros(5)` vs `np.array(5)`** - **`np.zeros(5)`**: - 输入为标量 `5` 时,NumPy 将其解释为 **形状参数** - 创建 **一维零数组**:长度为 5 的向量 - 示例: ```python >>> np.zeros(5) array([0., 0., 0., 0., 0.]) ``` - 形状:`(5,)`[^1][^3] - **`np.array(5)`**: - 输入为标量 `5` 时,NumPy 将其解释为 **数据内容** - 创建 **零维数组**(标量数组) - 示例: ```python >>> np.array(5) array(5) ``` - 形状:`()`[^2] #### 3. **`np.zeros((5,5))` vs `np.array((5,5))`** - **`np.zeros((5,5))`**: - 输入为元组 `(5,5)` 时,NumPy 将其解释为 **形状参数** - 创建 **二维零数组** - 行为与 `np.zeros([5,5])` 完全相同[^1][^3] - **`np.array((5,5))`**: - 输入为元组 `(5,5)` 时,NumPy 将其解释为 **数据内容** - 创建 **一维数组**:包含元素 `[5, 5]` - 行为与 `np.array([5,5])` 完全相同[^2][^4] --- ### 核心区别总结 | 函数/输入 | `[5,5]` | `5` | `(5,5)` | |-----------------|--------------------|--------------------|--------------------| | **`np.zeros`** | 二维数组 (5×5) | 一维数组 (长度=5) | 二维数组 (5×5) | | **`np.ones`** | 二维数组 (5×5) | 一维数组 (长度=5) | 二维数组 (5×5) | | **`np.array`** | 一维数组 (元素=5,5)| 零维数组 (标量=5) | 一维数组 (元素=5,5)| > **根本差异**: > - `np.zeros`/`np.ones` 的 **参数始终表示形状**,返回值是填充 0/1 的数组 > - `np.array` 的 **参数表示数据内容**,返回值是包含该数据的数组[^1][^2] --- ### 验证实验 ```python import numpy as np # zeros/ones 参数为形状 z1 = np.zeros([5,5]) # 二维数组 (5,5) z2 = np.zeros(5) # 一维数组 (5,) z3 = np.zeros((5,5)) # 二维数组 (5,5) # array 参数为数据内容 a1 = np.array([5,5]) # 一维数组 (2,) a2 = np.array(5) # 零维数组 () a3 = np.array((5,5)) # 一维数组 (2,) print("zeros([5,5]) 形状:", z1.shape) # (5,5) print("array([5,5]) 形状:", a1.shape) # (2,) print("zeros(5) 形状 :", z2.shape) # (5,) print("array(5) 形状 :", a2.shape) # () ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值