474. Ones and Zeroes

本文探讨了一道计算机科学领域的动态规划题目,旨在利用给定数量的0和1形成尽可能多的字符串组合。通过详细解析示例并提供C++代码实现,展示了如何使用动态规划解决该问题。

本周继续练习动态规划的相关题目。

题目:

In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.

For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s.

Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once.

Note:

  1. The given numbers of 0s and 1s will both not exceed 100
  2. The size of given string array won't exceed 600.

示例:

Example 1:

Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
Output: 4

Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”

 

Example 2:

Input: Array = {"10", "0", "1"}, m = 1, n = 1
Output: 2

Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".


题解:
  同样地,这道题需要通过动态规划来解决,因为不能贪心地去换尽量短的字符,当两个字符长度相同的时候,用贪心算法无法决定选哪一个。
  因此,这道题需要通过动态规划来解决。题目中给定m个0与n个1,dp[m][n]就标记了在当前的字符串序列下,能够用m个0与n个1取得的最多字符串。
  显然,dp[0][0] = 0,因为没有0与1可用的时候,必然得不到字符串
    dp[m][n] = max{dp[m][n],dp[m-m0][n-n0]+1}
  针对每一个字符串,实质上我们都采取两种策略,选这个字符串,还是不选。做决定之前,先统计这个字符串(第i个)有多少个0与1,分别记为m0与n0,如果不选这个字符串,那么dp[m][n]的值不会发生任何改变,但是选了之后,它的值就是用了m-m0个0 与n-n0个1,所得到的最多的字符串,也就是f[m-m0][n-n0]再加上1,有点类似于经典0-1背包问题
  
代码:
class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) { 
        // m个0 n个1
        vector<vector<int> > dp(m+1,vector<int>(n+1,0));
        for (int i = 0 ; i < strs.size();i++)
        {
            string curr = strs[i];
            int num0 = 0,num1 = 0;
            for(int j = 0; j < curr.length();j++)
            {
                if(curr[j] == '0') num0++;
                if(curr[j] == '1') num1++;
            }
            
            for(int j = m; j >=num0; j--)
            {
                for(int i = n;i >= num1 ;i--)
                {
                    dp[j][i] = max(dp[j][i],dp[j-num0][i-num1]+1);
                }
            }
            
        }
        
        return dp[m][n];
    }
};

 

 

转载于:https://www.cnblogs.com/MT-ComputerVision/p/6720195.html

<think>好的,我现在需要帮助用户解决在使用SimPEG和numpy进行电阻率建模时遇到的ValueError问题,具体错误是“The dimensions of the input argument 'var' are greater than is specified by 'shape'”。首先,我要回顾用户提供的引用和之前的对话内容,确保理解问题的背景。 用户之前提到了关于模型输入维度不匹配的问题,引用中提到了Numpy数组的大小不符合模型预期,以及通过reshape调整形状的例子。用户现在的问题集中在SimPEG中的电阻率模型设置,特别是var的维度超过指定的shape。 首先,我需要分析SimPEG中电阻率模型的常见设置步骤。SimPEG是一个地球物理正演模拟和反演工具,通常涉及定义网格、物理属性模型、正演问题等。电阻率模型通常是一个一维或二维的numpy数组,具体维度取决于网格结构。 可能的错误来源包括: 1. 电阻率模型数组的维度网格期望的形状不匹配。例如,网格可能是3D的,但模型数据是2D的,或者反之。 2. 在定义模型时使用了错误的网格参数,如网格层数、单元数量等。 3. 输入数据未正确展平或reshape,导致维度超出预期。 接下来,我需要参考用户提供的引用内容。引用2中提到通过reshape调整数组形状,比如将输入调整为[-1, 784],这可能适用于图像数据,但在电阻率模型中,网格结构可能不同,需要具体分析。 用户提到使用numpy设置电阻率模型,因此需要检查numpy数组的shape是否SimPEG要求的匹配。例如,如果网格是三维的,模型应该是三维数组,或者在某些情况下被展平为一维数组。 可能的解决方案步骤: 1. 检查网格定义:确认网格的维度(如mesh.dim)和单元数量(如mesh.nC),确保模型数组的shape之一致。 2. 检查模型赋值:确认将电阻率模型赋值给正确的位置,例如在物理属性映射时是否正确处理了维度。 3. 使用reshape或flatten调整数组形状,确保网格匹配。 4. 验证输入数据:在创建模型后,打印其shape并网格参数对比,确认一致。 另外,用户可能混淆了不同部分的输入,比如将三维模型数据传递到期望二维输入的函数中,或者在正演模拟时输入的源或接收器位置不正确,导致维度不匹配。 需要提醒用户检查SimPEG文档中的相关函数,确认输入参数的期望shape,并逐步调试代码,输出关键变量的shape信息,以定位问题所在。例如,在定义模型后立即打印shape,或者在设置正演问题前检查输入的参数。 最后,生成相关问题时要覆盖SimPEG的其他常见错误、网格定义、属性映射等,帮助用户扩展知识面,避免类似问题。</think>### 关于SimPEG电阻率建模中`ValueError: The dimensions of the input argument 'var' are greater than is specified by 'shape'`的分析 该错误通常发生在**输入参数的维度模型定义的预期形状不匹配**时。在SimPEG(地球物理正演反演框架)中,电阻率模型的设置需要严格匹配网格系统的维度定义和物理属性映射规则。以下是具体原因和解决方案: --- ### 1. **核心原因** - **网格模型维度不匹配**:SimPEG的网格系统(如`TensorMesh`或`TreeMesh`)定义了模型参数的形状。若电阻率模型(`numpy`数组)的维度(如三维数组)网格要求的维度(如二维或一维)不一致,则会触发此错误[^1]。 - **属性映射错误**:在将电阻率模型绑定到物理属性(如电导率)时,未正确使用`maps`模块,导致数据形状转换异常[^2]。 - **输入数据未展平**:某些SimPEG接口要求模型参数为一维数组(如反演参数),若未对多维数组调用`.flatten()`或`.reshape(-1)`,则会报错[^3]。 --- ### 2. **分步解决方案** #### 步骤1:验证网格定义 确保网格的维度电阻率模型匹配。例如,若使用三维网格,模型应为三维数组: ```python import numpy as np from SimPEG import Mesh # 定义三维网格(示例) mesh = Mesh.TensorMesh([np.ones(10), np.ones(20), np.ones(5)]) # 维度为 (10,20,5) print("网格维度:", mesh.dim) # 输出应为3 print("网格单元数量:", mesh.nC) # 总单元数为10*20*5=1000 # 电阻率模型应为三维数组或展平为一维数组(nC长度) resistivity_model = np.ones(mesh.nC) # 正确的一维模型 # 或三维数组(需网格形状一致) resistivity_model_3D = np.ones((10, 20, 5)) ``` #### 步骤2:检查物理属性映射 通过`maps`模块将模型参数映射到物理属性(如电导率): ```python from SimPEG.maps import IdentityMap # 创建映射(假设模型参数直接为电导率) sigma_map = IdentityMap(nP=mesh.nC) # nP必须模型参数长度一致 # 若模型为三维数组,需展平为一维 resistivity_model_flat = resistivity_model_3D.flatten() sigma = sigma_map * resistivity_model_flat # 映射后的电导率 ``` #### 步骤3:调试输入参数形状 在关键步骤打印数组形状,确保维度一致: ```python print("电阻率模型形状:", resistivity_model.shape) # 应为 (mesh.nC,) 或匹配网格维度 print("映射后电导率形状:", sigma.shape) # 应网格单元数一致 ``` #### 步骤4:修正输入参数的维度 若模型维度错误,使用`reshape`或`flatten`调整: ```python # 错误示例:二维数组输入到三维网格 resistivity_wrong = np.ones((10, 20)) # 二维数组 resistivity_corrected = resistivity_wrong.reshape(-1, 1, 1).repeat(5, axis=2) # 调整为三维 resistivity_corrected = resistivity_corrected.flatten() # 展平为一维 ``` --- ### 3. **示例代码修正** 假设在定义直流电阻率正演问题时出现错误: ```python from SimPEG.electromagnetics.static import resistivity as DC # 错误示例(模型未展平) resistivity_model = np.ones((10, 20, 5)) # 三维数组 survey = DC.Survey(...) # 省略survey定义 simulation = DC.Simulation3D( mesh=mesh, survey=survey, sigmaMap=sigma_map, # 直接传递三维数组会报错! # sigma=resistivity_model ) # 正确修正 sigma = sigma_map * resistivity_model.flatten() # 展平为一维 simulation = DC.Simulation3D( mesh=mesh, survey=survey, sigmaMap=sigma_map, sigma=sigma # 传递展平后的参数 ) ``` --- ### 4. **扩展验证** - **检查模型参数范围**:电阻率值需在合理范围内(如避免负值)。 - **网格兼容性**:若使用非结构化网格(如`TreeMesh`),模型参数长度必须等于网格单元数(`mesh.nC`)。 --- ### 相关问题 1. 如何在SimPEG中定义非结构化网格并绑定物理属性? 2. 如何通过`SimPEG.maps`模块实现各向异性电阻率映射? 3. 电阻率反演中如何设置正则化项以避免维度不匹配问题? 4. SimPEG中直流电阻率正演模拟的常见错误有哪些?如何调试? 通过以上步骤可系统性解决维度不匹配问题。若仍报错,建议逐步输出每个变量的`shape`并文档中的接口定义对比[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值