day36 力扣1049.最后一塊石頭的重量II 力扣494.目標和 力扣474.一和零

最后一塊石頭的重量II

有一堆石頭,用整數數組?stones?表示。其中?stones[i]?表示第?i?塊石頭的重量。

每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設石頭的重量分別為?x?和?y,且?x <= y。那么粉碎的可能結果如下:

  • 如果?x == y,那么兩塊石頭都會被完全粉碎;
  • 如果?x != y,那么重量為?x?的石頭將會完全粉碎,而重量為?y?的石頭新重量為?y-x

最后,最多只會剩下一塊?石頭。返回此石頭?最小的可能重量?。如果沒有石頭剩下,就返回?0

示例 1:

輸入:stones = [2,7,4,1,8,1]
輸出:1
解釋:
組合 2 和 4,得到 2,所以數組轉化為 [2,7,1,8,1],
組合 7 和 8,得到 1,所以數組轉化為 [2,1,1,1],
組合 2 和 1,得到 1,所以數組轉化為 [1,1,1],
組合 1 和 1,得到 0,所以數組轉化為 [1],這就是最優值。

示例 2:

輸入:stones = [31,26,33,21,40]
輸出:5

提示:

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 100

本題與分割等和子集很像。

使用滾動數組,dp[j]表示容量為j的背包所具有的價值(j容量的石頭價值也是j)

初始化均為0.

?遞推公式?要么沒使用i位置的石頭 就是dp[j];要么使用i位置的石頭 就是dp[j-stone[i]]+stone[i]。

順序,由于使用的是滾動數組,那我們就先遍歷物品,再遍歷容量,且容量遍歷是從后往前遍歷。

最后的輸出,我們得到了 dp[target], sum- dp[target]就是另一半的值,做差就可得到結果。

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {int sum = 0;for (int i : stones) {sum += i;}int target = sum / 2;vector<int> dp (target+1,0);for(int i = 0;i<stones.size();i++){for(int j = target;j>=stones[i];j--){dp[j] = max(dp[j],dp[j-stones[i]]+stones[i]);}}return (sum - dp[target]) - dp[target];}
};

目標和

給你一個非負整數數組 nums 和一個整數 target 。向數組中的每個整數前添加 '+' 或 '-' ,然后串聯起所有整數,可以構造一個 表達式 :例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串聯起來得到表達式 "+2-1" 。
返回可以通過上述方法構造的、運算結果等于 target 的不同 表達式 的數目。示例 1:輸入:nums = [1,1,1,1,1], target = 3
輸出:5
解釋:一共有 5 種方法讓最終目標和為 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3
示例 2:輸入:nums = [1], target = 1
輸出:1提示:1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000

假設加法的總和為x,那么減法對應的總和就是sum - x。

所以我們要求的是 x - (sum - x) = target

x = (target + sum) / 2

此時問題就轉化為,用nums裝滿容量為x的背包,有幾種方法

(C++代碼中,輸入的S 就是題目描述的 target)
if ((target + sum) % 2 == 1) return 0; // 此時沒有方案

同時如果target 的絕對值已經大于sum,那么也是沒有方案的。

if (abs(target) > sum) return 0; // 此時沒有方案
確定dp數組以及下標的含義

先用 二維 dp數組求解本題,dp[i][j]:使用 下標為[0, i]的nums[i]能夠湊滿j(包括j)這么大容量的包,有dp[i][j]種方法。

遞推公式

抽象化如下:

  • 不放物品i:即背包容量為j,里面不放物品i,裝滿有dp[i - 1][j]中方法。

  • 放物品i: 即:先空出物品i的容量,背包容量為(j - 物品i容量),放滿背包有 dp[i - 1][j - 物品i容量] 種方法。

if(nums[i]>j) dp[i][j] = dp[i-1][j];
else dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]; 

初始化?

最上方 把nums[0]=j 的dp[0][j]位置的dp初始化為1.

至于最左側的初始化,要考慮nums數組中有多少個0,如果沒有0,初始化為1;如果有n個0,初始化為2的n次方。

遍歷順序任意。

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for(int num:nums){sum += num;}if((sum+target)%2==1) return 0;if(abs(target)>sum) return 0;int bagSize = (sum+target)/2;vector<vector<int>> dp(nums.size(),vector<int>(bagSize+1,0));for(int i = 0;i<nums.size();i++){dp[i][0] = 1;}for(int j = 0;j<=bagSize;j++){if(j==nums[0]){dp[0][j] = 1;}}int numZero = 0;for (int i = 0; i < nums.size(); i++) {if (nums[i] == 0) numZero++;dp[i][0] = (int) pow(2.0, numZero);}for(int i = 1;i<nums.size();i++){for(int j = 1;j<=bagSize;j++){if(nums[i]>j) dp[i][j] = dp[i-1][j];else dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]; }}return dp[nums.size()-1][bagSize];}
};

?


一和零

給你一個二進制字符串數組?strs?和兩個整數?m?和?n?。

請你找出并返回?strs?的最大子集的長度,該子集中?最多?有?m?個?0?和?n?個?1?。

如果?x?的所有元素也是?y?的元素,集合?x?是集合?y?的?子集?。

示例 1:

輸入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
輸出:4
解釋:最多有 5 個 0 和 3 個 1 的最大子集是 {"10","0001","1","0"} ,因此答案是 4 。
其他滿足題意但較小的子集包括 {"0001","1"} 和 {"10","1","0"} 。{"111001"} 不滿足題意,因為它含 4 個 1 ,大于 n 的值 3 。

示例 2:

輸入:strs = ["10", "0", "1"], m = 1, n = 1
輸出:2
解釋:最大的子集是 {"0", "1"} ,所以答案是 2 。

提示:

  • 1 <= strs.length <= 600
  • 1 <= strs[i].length <= 100
  • strs[i]?僅由?'0'?和?'1'?組成
  • 1 <= m, n <= 100

確定dp數組(dp table)以及下標的含義

dp[i][j]:最多有i個0和j個1的strs的最大子集的大小為dp[i][j]

確定遞推公式:

dp[i][j] 可以由前一個strs里的字符串推導出來,strs里的字符串有zeroNum個0,oneNum個1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

然后我們在遍歷的過程中,取dp[i][j]的最大值。

所以遞推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

?順序均由后向前。

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(string str:strs){int oneNum = 0;int zeroNum = 0;for(char c:str){if(c=='0') zeroNum++;else oneNum++;}for(int i = m;i>=zeroNum;i--){for(int j = n;j>=oneNum;j--){dp[i][j] = max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);}}}return dp[m][n];}
};

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91797.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91797.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91797.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java內存模型(Java Memory Model,JMM)

?? JMM?? 是Java虛擬機&#xff08;JVM&#xff09;規范中定義的一組規則和規范&#xff0c;用于描述多線程環境下&#xff0c;Java程序中變量的訪問和修改行為&#xff0c;尤其是在并發編程中如何保證內存可見性、原子性和有序性。JMM 是 Java 并發編程的基石&…

【swoole Windows 開發(swoole-cli 開發 hyperf)】

先前swoole在Windows平臺的開發體驗極差&#xff0c;如果在Windows開發swoole的東西可以用docker或者虛擬機&#xff0c;遠程開發&#xff0c;體驗比較好的是直接Mac或者Linux系統開發。但是作為window平臺的釘子戶表示我窮。swoole之前已經推出了cygwin64編譯成winwods版本的方…

興達餐飲 酒店 進銷存管理系統軟件

興達餐飲 酒店 進銷存管理系統軟件

Seal Report:一款免費開源的報表工具

Seal Report 是一款基于 C# 語言開發的開源報表工具&#xff0c;可以從各種數據庫或 NoSQL 數據源中生成日常報告&#xff0c;并且執行復雜的計劃任務。 功能特性 免費開源&#xff1a;源代碼托管在 GitHub 上&#xff0c;用戶可以自由使用、修改、甚至集成到自己的系統中&…

WebRTC 多媒體 SDP 示例與解析

webRTC中的SDP的Bundlle可能包含一個或者多個媒體塊&#xff08;媒體描述, 源碼對應類ContentInfo&#xff09;&#xff0c;從 m 開始到下一個 m 行&#xff08;或 SDP 結束&#xff09;之間的所有屬性&#xff08;包括 a&#xff09;都屬于同一個媒體塊&#xff08;media sect…

SpringBoot 啟動富文本文字更改

正常來說 SpringBoot啟動時候&#xff0c;展示的文字是這個 、 主播這邊想要換一個樣式&#xff0c;換一個自己自定義的文字 這邊換成了自己的博客名字 具體實現操作如下 在項目目錄 resources下創建一個名字為banner.txt的文本&#xff0c;這是SpringBoot啟動的時候尋找的…

基于結構熵權-云模型的鑄鐵浴缸生產工藝安全評價

一、評價模型核心思想 結構熵權法 解決傳統熵權法忽略指標間結構關系的問題,通過指標層次網絡計算權重。 步驟: 構建工藝安全評價指標體系(樹狀/網絡結構) 計算同級指標間的影響度矩陣 引入修正熵權:wj=1?Ej∑(1?Ek)結構影響因子w_j = \frac{1 - E_j}{\sum (1 - E_k)} \…

[Linux]從零開始的vs code交叉調試arm Linux程序教程

一、前言 最近的項目中需要集成rknn的視覺識別&#xff0c;在這之前我并且沒有將rknn集成到自己項目的經驗。這里我需要在rknn原本demo的基礎上我還需要集成自己的業務代碼。但是又有一個問題&#xff0c;原本rknn我們都是使用交叉編譯編譯到開發板上的&#xff0c;并且我們還要…

視頻號私信自動化回復插件

給自己的瀏覽器插件又增加了視頻號斯信的自動化回復搜索&#xff1a;程序員老狼主體邏輯就是&#xff0c;不停的點擊打招呼和斯信那個tab切換查看有無小紅點&#xff0c;有小紅點的會話&#xff0c;就點擊。查看有無打招呼&#xff0c;有打招呼就點擊&#xff0c;抓取昵稱和內容…

Web前端實現銀河粒子流動特效的3種技術方案對比與實踐

文章目錄 前端實現銀河粒子流動特效的技術原理與實踐 引言:銀河粒子特效的技術背景與現狀 技術發展歷史 當前技術現狀 技術原理與實現方案 思維導圖:銀河粒子特效技術架構 1. CSS3實現方案 基礎實現代碼 性能優化技巧 2. Canvas 2D實現方案 基礎實現代碼 Canvas高級優化技術 …

Linux:告別Jammy,擁抱Noble!WSL Ubuntu 22.04 到 24.04 LTS 終極升級指南

大家好&#xff01;如果大家和我一樣&#xff0c;是Windows Subsystem for Linux (WSL) 的忠實用戶&#xff0c;那么大家一定對Ubuntu在其中的表現印象深刻。我們中的許多人可能還在使用穩定可靠的Ubuntu 22.04 LTS (Jammy Jellyfish)。但現在&#xff0c;一個更令人興奮的時代…

江協科技STM32 11-1 SPI通信協議

本節課我們將繼續學習下一個通信協議&#xff0c;SPI。SPI通信和我們剛剛學習過的I2C通信差不多。兩個協議的設計目的都一樣都是實現主控芯片和各種外掛芯片之間的數據交流&#xff0c;有了數據交流的能力&#xff0c;我們的主控芯片就可以掛載并操縱各式各樣的外部芯片&#x…

預過濾環境光貼圖制作教程:第一步 - HDR 轉立方體貼圖

在基于物理的渲染(PBR)中,環境光貼圖是實現真實光照效果的核心組件之一。而將 HDR 全景圖轉換為立方體貼圖,是制作預過濾環境光貼圖的基礎步驟。本教程將詳細講解如何實現這一轉換過程。 什么是 HDR 轉立方體貼圖? HDR(高動態范圍)全景圖通常以等矩形投影(Equirectan…

02 深度學習介紹【動手學深度學習v2】| 學習筆記

1、intro自然語言處理雖然我們過去取得了很大的進展&#xff0c;但是實際上還是停留在感知層面。計算機視覺領域&#xff0c;因為圖片里面都是像素&#xff0c;像素很難用符號學來解釋&#xff0c;所以計算機視覺大部分是用概率模型或機器學習來做。深度學習它是機器學習的一種…

智能學號抽取系統V5.6.4重磅發布

告別隨機數&#xff0c;擁抱智能點名&#xff01;—— 全新升級的“智能學號抽取系統V5.6.4”重磅發布&#xff01; 摘要&#xff1a; 還在為課堂隨機提問、活動抽獎而手動翻名單、查表格而煩惱嗎&#xff1f;還在忍受傳統點名工具的簡陋和不智能嗎&#xff1f;今天&#xff0…

Leetcode-141.環形鏈表

dict和set 1. 結構上的區別&#xff1a;類型鍵&#xff08;Key&#xff09;值&#xff08;Value&#xff09;示例dict有有{a: 1, b: 2}set有沒有{a, b} dict 是**鍵值對&#xff08;key-value&#xff09;**的集合。set 是只有鍵&#xff08;key&#xff09;沒有值的一組唯一元…

調節步進電機速度時調PSC和調ARR的區別

在步進電機控制中&#xff0c;調節速度通常是通過改變脈沖頻率實現的。代碼中選擇調節ARR&#xff08;Auto-Reload Register&#xff09;而非PSC&#xff08;Prescaler&#xff09;的原因如下&#xff1a; 1. ARR 與 PSC 的核心區別 ? ARR&#xff08;自動重載寄存器&#xff…

在 AKS 中運行 Azure DevOps 私有代理-1

簡介 配置 Azure DevOps 私有代理的傳統方法是將其部署在虛擬機 (VM) 上。然而,一個有趣的替代方案是利用 Azure Kubernetes 服務 (AKS) 來實現此目的。 本文將指導您如何使用 Helm Chart 在 AKS 集群中設置 Azure DevOps 私有代理,并提供該過程的分步說明。 在 AKS 中部署…

C# _Json數據

目錄 1、添加Json庫 2、數據序列化&#xff08;對象轉 JSON&#xff09;和反序列化&#xff08;JSON 轉對象&#xff09;操作 3、序列化 創建和讀取Json數據 創建Json數據 定義一個CreateJson方法 讀取 解析 Json數據 定義一個ReadJson方法 4、程序運行結果 在 C# 中&…

JavaScript 原始值與引用值

JavaScript 原始值與引用值 ECMAScript變量可以包含兩種不同類型的數據&#xff1a;原始值和引用值。 原始值&#xff08;primitive value&#xff09;就是最簡單的數據&#xff0c;引用值&#xff08;reference value&#xff09;則是由多個值構成的對象。 保存原始值的變量是…