杭電oj(1087、1203、1003)題解

DP 即動態規劃(Dynamic Programming),是一種通過把原問題分解為相對簡單的子問題,并保存子問題的解來避免重復計算,從而解決復雜問題的算法策略。以下從幾個方面簡述動態規劃:

基本思想

動態規劃的核心在于 “分治” 和 “最優子結構”。它將一個復雜問題分解為一系列相互關聯的子問題,通過求解子問題并保存其解,避免對相同子問題的重復求解,從而減少計算量。同時,原問題的最優解可以由子問題的最優解組合而成,這就是最優子結構性質。

適用條件

  • 最優子結構性質:問題的最優解包含其子問題的最優解。即可以通過子問題的最優解推導出原問題的最優解。例如,在背包問題中,對于一個容量為?W?的背包和?n?個物品,要得到其最優裝法,可以先考慮容量為?W - w[i]w[i]?為第?i?個物品的重量)的背包和前?n - 1?個物品的最優裝法。
  • 子問題重疊性質:在求解過程中,會多次遇到相同的子問題。動態規劃通過保存子問題的解,避免了對這些子問題的重復計算,從而提高了效率。比如在斐波那契數列的計算中,直接遞歸計算會有大量重復的子問題計算,而使用動態規劃可以避免這種情況。

求解步驟

  1. 定義狀態:明確問題的狀態表示,即如何用一個或多個變量來描述子問題。例如,在最長上升子序列問題中,可以定義狀態?dp[i]?表示以第?i?個元素結尾的最長上升子序列的長度。
  2. 確定狀態轉移方程:根據問題的最優子結構性質,找出狀態之間的轉移關系。狀態轉移方程描述了如何從子問題的解推導出原問題的解。例如,在最長上升子序列問題中,狀態轉移方程為?dp[i] = max(dp[j] + 1) (0 <= j < i 且 a[j] < a[i])
  3. 初始化:確定初始狀態的值,這些初始狀態是問題的邊界條件。例如,在斐波那契數列的動態規劃求解中,dp[0] = 0dp[1] = 1?就是初始狀態。
  4. 計算順序:根據狀態轉移方程,確定計算狀態的順序,一般是從簡單的子問題開始,逐步求解更復雜的問題。

應用場景

動態規劃在很多領域都有廣泛的應用,常見的問題包括:

  • 背包問題:如 0 - 1 背包問題、完全背包問題等,用于在一定的約束條件下選擇物品,使得總價值最大。
  • 最長公共子序列問題:找出兩個序列中最長的公共子序列,在生物信息學、版本控制等領域有應用。
  • 最短路徑問題:如 Floyd - Warshall 算法,用于求解圖中任意兩點之間的最短路徑。
  • 資源分配問題:在多個項目或任務之間分配資源,以達到最優的效益。

目錄

1087

題目

思路

代碼詳細步驟

動態規劃初始化

狀態轉移

找出最大值

代碼

1203

題目

思路

代碼

1003

題目

思路

代碼


1087

題目

思路

動態規劃算法的核心在于將原問題分解為一系列子問題,并通過求解子問題來得到原問題的解。在這個問題中,我們定義狀態?dp[i]?表示以第?i?個元素結尾的最長上升子序列的最大和。通過遍歷序列中的每個元素,我們可以根據之前的狀態來更新當前狀態,最終找出所有狀態中的最大值,即為最長上升子序列的最大和。

代碼詳細步驟

動態規劃初始化
  • dp[0]=a[0];:將?dp[0]?初始化為?a[0],因為以第一個元素結尾的最長上升子序列就是它本身,其和就是?a[0]
狀態轉移
  • 外層循環?for(int i = 1; i < n; i++):遍歷數組中的每個元素,從第二個元素開始。
  • dp[i]=a[i];:將?dp[i]?初始化為?a[i],表示以第?i?個元素結尾的最長上升子序列至少包含該元素本身。
  • 內層循環?for(int j = 0; j < i; j++):遍歷當前元素?a[i]?之前的所有元素。
  • if(a[i]>a[j]):判斷?a[i]?是否大于?a[j],如果滿足條件,說明可以將?a[i]?接到以?a[j]?結尾的最長上升子序列后面。
  • dp[i]=max(a[i]+dp[j],dp[i]);:更新?dp[i]?的值,取?a[i] + dp[j]?和?dp[i]?中的最大值。a[i] + dp[j]?表示將?a[i]?接到以?a[j]?結尾的最長上升子序列后面得到的新子序列的和。
找出最大值
  • int maxnum=-1e9;:將?maxnum?初始化為一個較小的值?-1e9,確保后續找到的任何?dp[i]?值都能更新?maxnum
  • for(int i = 0; i < n; i++){ maxnum=max(maxnum,dp[i]); }:遍歷?dp?數組,找出其中的最大值。

代碼

#include<iostream>
#include<algorithm>
using namespace std;
int dp[1010],a[1010],n; 
int main(){while(cin>>n&&n){for(int i=0;i<n;i++){cin>>a[i];}dp[0]=a[0];for(int i=1;i<n;i++){dp[i]=a[i];for(int j=0;j<i;j++){if(a[i]>a[j]){dp[i]=max(a[i]+dp[j],dp[i]);}}}int maxnum=-1e9;for(int i=0;i<n;i++){maxnum=max(maxnum,dp[i]);}cout<<maxnum<<endl;}return 0;
}

1203

題目

思路

外層循環?for(int i = 0; i < m; i++):遍歷每一個物品。

內層循環?for(int j = n; j >= a[i]; j--):從背包的總容量?n?開始,倒序遍歷到當前物品的重量?a[i]。倒序遍歷是為了保證每個物品只被選擇一次,這是 0 - 1 背包問題的常見處理方式。

狀態轉移方程?dp[j]=max(dp[j],dp[j-a[i]]+prob[i]-dp[j-a[i]]*prob[i]);

dp[j]?表示不選擇當前物品?i?時,背包容量為?j?的最大成功概率。

dp[j - a[i]]?表示在不放入當前物品?i?時,背包容量為?j - a[i]?的最大成功概率。

dp[j - a[i]] + prob[i] - dp[j - a[i]] * prob[i]?表示選擇當前物品?i?時的成功概率。這里基于概率的計算原理,假設物品的成功是相互獨立事件,使用公式?P(A 或 B) = P(A) + P(B) - P(A) * P(B)?來計算選擇當前物品后的成功概率。

通過?max?函數取兩者中的最大值更新?dp[j]

代碼

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
double dp[N];
double prob[N];
int a[N];
int n,m;
int main(){while(cin>>n>>m){if(n==0 && m==0) break;for(int i=0;i<m;i++){cin>>a[i]>>prob[i];}memset(dp,0,sizeof(dp));for(int i=0;i<m;i++){for(int j=n;j>=a[i];j--){dp[j]=max(dp[j],dp[j-a[i]]+prob[i]-dp[j-a[i]]*prob[i]);}}printf("%.1lf%%\n",dp[n]*100);}return 0;
}

1003

題目

思路

狀態轉移方程?dp[j]=max(dp[j],dp[j-a[i]]+prob[i]-dp[j-a[i]]*prob[i]);

dp[j]?表示不選擇當前物品?i?時,背包容量為?j?的最大成功概率。

dp[j - a[i]]?表示在不放入當前物品?i?時,背包容量為?j - a[i]?的最大成功概率。

dp[j - a[i]] + prob[i] - dp[j - a[i]] * prob[i]?表示選擇當前物品?i?時的成功概率。這里基于概率的計算原理,假設物品的成功是相互獨立事件,使用公式?P(A 或 B) = P(A) + P(B) - P(A) * P(B)?來計算選擇當前物品后的成功概率。

通過?max?函數取兩者中的最大值更新?dp[j]

代碼

#include<iostream>
using namespace std;
int n,m,l,r,maxnum,sum,temp,num;
int main(){cin>>n;for(int i=0;i<n;i++){l=0,r=0,temp=1,maxnum=-20000,sum=0;cin>>m;for(int j=1;j<=m;j++){cin>>num;sum+=num;if(sum>maxnum){r=j;maxnum=sum;l=temp;}if(sum<0){temp=j+1;sum=0;}}cout<<"Case "<<(i+1)<<":"<<endl<<maxnum<<" "<<l<<" "<<r<<endl;if(i<n-1) cout<<endl;}return 0;
}

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

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

相關文章

一鍵多環境構建——用 Hvigor 玩轉 HarmonyOS Next

引言 在 HarmonyOS Next 的應用開發中&#xff0c;常常需要針對不同環境&#xff08;測試、預發、線上&#xff09;或不同簽名&#xff08;調試、正式&#xff09;輸出多個 APP/HAP 包。雖然 HarmonyOS 提供了多目標構建&#xff08;Multi-Target Build&#xff09;能力&#…

qt/c++云對象瀏覽器

簡介 本項目為基于QT5和C11的云對象存儲可視化管理工具 源碼獲取 int main(){ printf("源碼聯系綠泡泡:%s","joyfelic"); return 0; }

【Ubuntu】提升 docker ps -a 輸出的可讀性:讓 Docker 容器狀態更清晰

提升 docker ps -a 輸出的可讀性&#xff1a;讓 Docker 容器狀態更清晰 當我們使用 docker ps -a 查看所有 Docker 容器時&#xff0c;輸出的信息通常會非常多&#xff0c;尤其是在容器數量較多時。默認輸出中包含容器 ID、名稱、鏡像、狀態、端口等信息&#xff0c;容易讓人眼…

Spring Security自定義身份認證

盡管項目啟動時&#xff0c;Spring Security會提供了默認的用戶信息&#xff0c;可以快速認證和啟動&#xff0c;但大多數應用程序都希望使用自定義的用戶認證。對于自定義用戶認證&#xff0c;Spring Security提供了多種認證方式&#xff0c;常用的有In-Memory Authentication…

在亞馬遜云服務器上部署WordPress服務

在亞馬遜云服務器上部署WordPress服務第一步&#xff1a;創建EC2實例第二步&#xff1a;初始設置與安裝第三步&#xff1a;配置MySQL與WordPress第四步&#xff1a;配置Apache與WordPress第五步&#xff1a;訪問WordPress第六步&#xff1a;測試數據庫連接第七步&#xff1a;使…

Web3.0的認知補充(去中心化)

涉及開發技術&#xff1a; Vue Web3.js Solidity 基本認知 Web3.0含義&#xff1a; 新一代互聯網思想&#xff1a;去中心化及用戶為中心的互聯網 數據&#xff1a;可讀可寫可授權 核心技術&#xff1a;區塊鏈、NFT 應用&#xff1a;互聯網上應用 NFT &…

如何修復寶可夢時時刻刻冒險無法正常工作

寶可夢的時時刻刻冒險模式是一項強大的功能&#xff0c;即使應用程序關閉&#xff0c;它也能追蹤你的步行距離。它的工作原理是將你的步數與 iOS 上的 Apple Health 或 Android 上的 Google Fit 同步。它對于孵化寶可夢蛋和賺取好友糖果至關重要&#xff0c;但一旦它停止工作&a…

redis常用集合操作命令

在 Redis 的命令行界面&#xff08;redis-cli&#xff09;中&#xff0c; Redis 的集合&#xff08;Set&#xff09;是無序的&#xff0c;且集合中的元素是唯一的。Redis 本身沒有直接提供獲取集合中某個特定屬性的命令&#xff0c;因為集合中的元素是簡單的值&#xff0c;而不…

初識數據結構——二叉樹從基礎概念到實踐應用

數據結構專欄 ?(click) 初識二叉樹&#xff1a;從基礎概念到實踐應用&#x1f333; 一、樹型結構基礎 1.1 樹的基本概念 樹是一種非線性的數據結構&#xff0c;由n(n>0)個有限節點組成一個具有層次關系的集合。它看起來像一棵倒掛的樹&#xff0c;根朝上而葉朝下。 關鍵特…

駝峰命名法(Camel Case)與匈牙利命名法(Hungarian Notation)詳解

駝峰命名法&#xff08;Camel Case&#xff09;與匈牙利命名法&#xff08;Hungarian Notation&#xff09;詳解及對比? ?1. 駝峰命名法&#xff08;Camel Case&#xff09;? ?定義? 駝峰命名法&#xff08;Camel Case&#xff09;是一種變量、函數、類等標識符的命名方…

keil 中優化等級的bug

一&#xff0c;問題描述 程序中代碼有的執行&#xff0c;有的不執行&#xff0c;仔細研究&#xff0c;查詢人工智能。 程序中printf打印后面的代碼不執行&#xff0c; 然后過幾十個函數又開始正常了。 二.分析問題 跳過函數一般又判斷和Goto等語句&#xff0c;其它的溢出和錯誤…

織夢dedecms網站如何修改上一篇下一篇的標題字數

一般情況下&#xff0c;如果你的上一篇和下一篇是2行布局就不需要限制標題的字數了&#xff0c;如果你要一行布局上一篇和下一篇標題過長就會打亂網頁布局&#xff0c;那么限制上一篇和下一篇的標題字數是需要的&#xff0c;避免頁面看起來雜亂不堪。 織夢dedecms網站如何修改…

信創系統 sudoers 權限配置實戰!從小白到高手

好文鏈接&#xff1a;實戰&#xff01;銀河麒麟 KYSEC 安全中心執行控制高級配置指南 Hello&#xff0c;大家好啊&#xff01;今天給大家帶來一篇關于信創終端操作系統中 sudoers 文件詳解的實用文章&#xff01;在 Linux 系統中&#xff0c;sudo 是一項非常重要的權限控制機制…

《明解C語言入門篇》讀書筆記四

目錄 第四章&#xff1a;程序的循環控制 第一節&#xff1a;do語句 do語句 復合語句&#xff08;程序塊&#xff09;中的聲明 讀取一定范圍內的值 邏輯非運算符 德摩根定律 德摩根定律 求多個整數的和及平均值 復合賦值運算符 后置遞增運算符和后置遞減運算符 練習…

vite+vue2+elementui構建之 vite.config.js

webpack版本太低&#xff0c;構建依賴太多&#xff0c;頭大。 各種查閱資料&#xff0c;弄了一份直通構建vite構建elementUi核心文件&#xff0c; 構建基于開源若依vue2vue3版本改造&#xff0c;感謝開源&#xff0c;感謝若依。 package.json 地址 vitevue2elementui構建之…

超參數詳解:從基礎概念到優化策略的全面指南

摘要 本文深入解析機器學習中超參數的核心概念&#xff0c;詳細對比參數與超參數的本質區別&#xff0c;系統介紹學習率、隱含層數量等常見超參數類型&#xff0c;以及網格搜索、貝葉斯優化等主流尋優方法。結合超參數搜索的標準流程&#xff0c;通過具體案例演示如何高效調整…

計算機視覺與深度學習 | LSTM原理及與卡爾曼濾波的融合

長短期記憶網絡(LSTM)是一種特殊的循環神經網絡(RNN),旨在解決傳統RNN在處理長序列數據時出現的梯度消失和梯度爆炸問題。以下為你詳細介紹其基本原理: 核心思想:LSTM的核心思想是引入記憶單元和門控機制來控制信息的流動,從而解決傳統RNN的梯度消失問題。記憶單元類似…

EXCEL常用函數公式和VBA匯總第二篇

系列文章目錄 文章目錄 系列文章目錄前言一、excel公式應用1.rand函數2.rand函數隨機排序3.rand函數提取數據4.correl函數5.SUBSTITUTE函數6.MAX組合函數7.分析下班時間8.柏拉圖自動排序 總結 前言 一、excel公式應用 1.rand函數 用excel生成1-5的隨機數字&#xff0c;其中對…

iOS 類與對象底層原理

iOS 類與對象底層原理 文章目錄 iOS 類與對象底層原理探索對象本質objc_setProperty 源碼cls與類的關聯原理聯合體isa的類型isa_t 原理探索initIsa方法通過setClass方法中的shiftcls來驗證綁定的一個流程通過 isa & ISA_MSAK通過object_getClass通過位運算 類&類的結構…

浮點數:IEEE 754標準

IEEE 754 標準是一種由電氣和電子工程師協會&#xff08;IEEE&#xff09;制定的浮點數表示的標準&#xff0c;廣泛應用于計算機系統中&#xff0c;下面是詳細介紹&#xff1a; 歷史背景 在 IEEE 754 標準出現之前&#xff0c;不同的計算機系統采用各自的浮點數表示方法&…