【九十四】【算法分析與設計】練習四蠻力法練習,排列問題和組合問題,求解最大連續子序列和問題,求解冪集問題,求解0/1背包問題,求解任務分配問題

求解最大連續子序列和問題

給定一個有n(n≥1)個整數的序列,要求求出其中最大連續子序列的和。

例如:

序列(-2,11,-4,13,-5,-2)的最大子序列和為20

序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大子序列和為16。

規定一個序列最大連續子序列和至少是0(看成0個元素構成的子序列),如果小于0,其結果為0。

1.

子數組累加和最大值問題,如何劃分問題,子數組應該如何劃分?

可以劃分為以某一個位置結尾的子數組,以i位置結尾的子數組.

所有的子數組被劃分成以0下標結尾的子數組,以1下標結尾的子數組.......

我們只需要解決每一個劃分出來的子數組集合對應的問題即可.

也就是解決以某一個位置結尾的子數組累加和最大值是多少.

2.

以i位置結尾的子數組可以劃分成兩種,第一種是只包含i位置元素,第二種是不只包含i位置元素.

只包含i位置元素的累加和最大值為arr[i],不只包含i位置元素的累加和最大值為arr[i]+(以i-1位置結尾的子數組累加和最大值).

我們要求最大值,所以以i位置結尾的子數組累加和最大值為max(arr[i],arr[i]+(以i-1位置結尾的子數組累加和最大值)).

3.

動態規劃,自底向上的動態規劃和自頂向下的動態規劃.

自底向上的動態規劃寫法

 
#include<bits/stdc++.h> // 導入標準庫頭文件
using namespace std; // 使用標準命名空間
#define int long long // 將int類型定義為long long類型,便于處理大數
#define endl '\n' // 將endl定義為換行符// 定義兩個測試用的數組
vector<int>arr1 = { -2,11,-4,13,-5,-2 };
vector<int>arr2 = { -6,2,4,-7,5,3,2,-1,6,-9,10,-2 };// 定義一個動態規劃數組和一個存儲當前數組的變量
vector<int>dp;
vector<int>arr;
// 定義存儲最大子數組和的變量
int ret;// 初始化函數
void init() {dp.assign(arr.size(), 0); // 將dp數組初始化為和當前數組相同大小,并賦初值為0ret = 0; // 將ret初始化為0
}// 求解最大子數組和的函數
void solve() {for (int i = 0; i < arr.size(); i++) { // 遍歷數組中的每一個元素dp[i] = max((i - 1 >= 0 ? dp[i - 1] : 0) + arr[i], arr[i]); // 計算以當前位置結尾的最大子數組和ret = max(ret, dp[i]); // 更新最大子數組和}cout << ret << endl; // 輸出結果
}// 測試函數
void f() {arr = arr1; // 將數組設置為arr1init(); // 初始化solve(); // 求解arr = arr2; // 將數組設置為arr2init(); // 初始化solve(); // 求解
}// 主函數
signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高輸入輸出效率f(); // 調用測試函數
}

自頂向下的動態規劃寫法(記憶化遞歸)

 
#include<bits/stdc++.h> // 導入標準庫頭文件
using namespace std; // 使用標準命名空間
#define int long long // 將int類型定義為long long類型,便于處理大數
#define endl '\n' // 將endl定義為換行符// 定義兩個測試用的數組
vector<int>arr1 = { -2,11,-4,13,-5,-2 };
vector<int>arr2 = { -6,2,4,-7,5,3,2,-1,6,-9,10,-2 };// 定義一個當前數組的變量和一個存儲最大子數組和的變量
vector<int>arr;
int ret;// 定義一個動態規劃數組
vector<int>dp;// 記憶化遞歸函數,求以位置i結尾的最大子數組和
int dfs(int i) {if (dp[i] != -1) return dp[i]; // 如果dp[i]已被計算,則直接返回dp[i]if (i - 1 < 0) { // 如果i是第一個元素dp[i] = arr[i]; // 直接返回arr[i]return dp[i]; // 返回dp[i]}dp[i] = max(dfs(i - 1) + arr[i], arr[i]); // 計算dp[i],取包含i的子數組和與僅包含i元素的子數組和的最大值ret = max(ret, dp[i]); // 更新最大子數組和return dp[i]; // 返回dp[i]
}// 初始化函數
void init() {ret = 0; // 將ret初始化為0dp.assign(arr.size(), -1); // 將dp數組初始化為和當前數組相同大小,并賦初值為-1
}// 求解最大子數組和的函數
void solve() {for (int i = 0; i < dp.size(); i++) dfs(i); // 遍歷數組中的每一個元素,調用dfs函數cout << ret << endl; // 輸出結果
}// 測試函數
void f() {arr = arr1; // 將數組設置為arr1init(); // 初始化solve(); // 求解arr = arr2; // 將數組設置為arr2init(); // 初始化solve(); // 求解
}// 主函數
signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高輸入輸出效率f(); // 調用測試函數
}

求解冪集問題

對于給定的正整數3,求1~3構成的集合的所有子集(冪集)。

{}

{1}

{2}

{1,2}

{3}

{1,3}

{2,3}

{1,2,3}

1.

組合問題,有3個整數,選出其中的部分整數作為一個集合,所有不同的情況都列出來.

對于任意的整數,在選出來的集合中,都可以選擇或者不選擇兩種方案.

所以一共有2^3種方案.對于數字1可以選擇或者不選擇,對于數字2可以選擇或者不選擇,對于數字3可以選擇或者不選擇.

一共有2*2*2=2^3種方案數.

2.

在每一種方案中對于每一個數字,都有對應的選擇,選擇或者不選擇,因此可以用1表示選擇0表示不選擇.

例如空集對應000,{1}對應100,{2}對應010,{1,2}對應110....{1,2,3}對應111.

如果000~111全部是二進制數,那么對應的十進制數是0~2^3-1.

每一個數的二進制都對應一種方案.

3.

對于每一種方案,只需要提取對于二進制數所有位置的1就知道選擇了哪些元素.

 
#include<bits/stdc++.h> // 導入標準庫頭文件
using namespace std; // 使用標準命名空間
#define int long long // 將int類型定義為long long類型,便于處理大數
#define endl '\n' // 將endl定義為換行符// 定義一個包含1,2,3的數組
vector<int> arr = { 1,2,3 };
// 定義一個變量n來存儲冪集的大小
int n;// 初始化函數
void init() {n = pow(2, arr.size()); // 計算冪集的大小,即2的arr.size()次冪
}// 求解冪集的函數
void solve() {for (int i = 0; i < n; i++) { // 遍歷從0到2^arr.size() - 1的所有整數cout << "{ "; // 輸出子集的左花括號for (int j = 0; j < arr.size(); j++) { // 遍歷數組中的每一個元素if (i & (1 << j)) { // 檢查整數i的第j位是否為1cout << arr[j] << " "; // 如果是,則輸出對應的數組元素}}cout << "}" << endl; // 輸出子集的右花括號和換行符}
}// 主函數
signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高輸入輸出效率init(); // 初始化solve(); // 求解冪集
}

求解0/1背包問題

有n個重量分別為{w1,w2,…,wn}的物品,它們的價值分別為{v1,v2,…,vn},給定一個容量為W的背包。設計從這些物品中選取一部分物品放入該背包的方案,每個物品要么選中要么不選中,要求選中的物品不僅能夠放到背包中,而且具有最大的價值。

并對下表所示的4個物品求出W=6時的所有解和最佳解。

物品編號

重量

價值

1

5

4

2

3

4

3

2

3

4

1

1

1.

0/1背包問題也是組合問題.有n個物品,選擇一部分物品出來放到一個集合里面.

2.

一共有4個物品,每一個物品對應一個二進制數,一共是四個位置的二進制數,0~2^4-1.

每一個數對應一種選擇方案,要么選擇要么不選擇.

一共有2^4種方案數.

3.

printf輸入格式很方便,但是要注意string轉化為c_str().

 
#include<bits/stdc++.h> // 導入標準庫頭文件
using namespace std; // 使用標準命名空間
#define int long long // 將int類型定義為long long類型,便于處理大數
#define endl '\n' // 將endl定義為換行符// 定義一個結構體node,用來存儲物品的重量和價值
struct node {int weight; // 物品重量int value; // 物品價值
};// 定義變量n表示物品數量,nsize表示所有可能選擇方案的數量,maxWeight表示背包的最大承重
int n = 0;
int nsize = 0;
int maxWeight = 6; // 背包最大承重為6// 定義一個包含4個物品的數組,每個物品包含重量和價值
vector<node> arr = { {5,4},{3,4},{2,3},{1,1} };// 定義一個結構體node1,用來存儲選擇方案的字符串表示、總重量和總價值
struct node1 {string str = ""; // 選擇方案的字符串表示int weight = 0; // 選擇方案的總重量int value = 0; // 選擇方案的總價值
};// 定義一個變量ret,用來存儲最佳選擇方案
node1 ret;// 初始化函數
void init() {n = 4; // 物品數量為4nsize = pow(2, n); // 所有可能選擇方案的數量為2^4=16
}// 求解0/1背包問題的函數
void solve() {cout << "0/1背包求解方案" << endl; // 輸出標題// 輸出表頭printf("%-10s%-20s%-10s%-10s%-10s\n", "序號", "選中物品", "總重量", "總價值", "能否裝入");for (int i = 0; i < nsize; i++) { // 遍歷所有可能的選擇方案node1 temp; // 定義一個臨時變量temp來存儲當前選擇方案temp.str.push_back('{'); // 添加左花括號temp.str.push_back(' ');for (int j = 0; j < n; j++) { // 遍歷所有物品if (i & (1 << j)) { // 檢查當前選擇方案是否選擇了第j個物品temp.str.push_back(j + '1'); // 如果選擇了,則將物品編號添加到字符串中temp.str.push_back(' ');temp.weight += arr[j].weight; // 將物品的重量加到總重量中temp.value += arr[j].value; // 將物品的價值加到總價值中}}temp.str.push_back('}'); // 添加右花括號// 如果當前選擇方案的總重量小于等于背包的最大承重且總價值大于當前最佳選擇方案的總價值,則更新最佳選擇方案if (temp.weight <= maxWeight && temp.value > ret.value) ret = temp;// 輸出當前選擇方案的序號、字符串表示、總重量、總價值和是否能裝入背包printf("%-10lld%-20s%-10lld%-10lld%-10s\n", i + 1, temp.str.c_str(), temp.weight, temp.value, temp.weight <= maxWeight ? "能" : "否");}// 輸出最佳選擇方案的字符串表示、總重量和總價值printf("最佳方案為 選中物品:%s,總重量:%lld,總價值:%lld", ret.str.c_str(), ret.weight, ret.value);
}// 主函數
signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高輸入輸出效率init(); // 初始化solve(); // 求解0/1背包問題
}

求解任務分配問題

有n(n≥1)個任務需要分配給n個人執行,每個任務只能分配給一個人,每個人只能執行一個任務。

第i個人執行第j個任務的成本是c[i][j](1≤i,j≤n)。求出總成本最小的分配方案

【問題求解】所謂一種分配方案就是由第i個人執行第j個任務,用(a1,a2,…,an)表示,即第1個人執行第a1個任務,第2個人執行第a2個任務,以此類推。全部的分配方案恰好是1~n的全排列。

這里采用窮舉法求出所有的分配方案ps(全排列),再計算出每種方案的成本,比較求出最小成本的方案,即最優方案。以n=4,成本如下表所示為例討論。

1.

排列問題,將4個任務進行全排列,列出所有的情況.

用內置函數next_premutation函數找到所有的全排序序列.

模板:

 
        vector<int> arr = { 1,2,3,4 };do {// 輸出當前的排列for (int num : arr) {cout << num << " ";}cout << endl;} while (next_permutation(arr.begin(), arr.end()));

2.

用內置函數next_premutation找到所有的全排序序列的前提是需要arr排序完畢.

 

//內置函數求全排序模板
#if 0#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
void init() {}
void solve() {}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);init();solve();vector<int> arr = { 1,2,3,4 };do {// 輸出當前的排列for (int num : arr) {cout << num << " ";}cout << endl;} while (next_permutation(arr.begin(), arr.end()));}#endif // 1#if 1#include<bits/stdc++.h> // 導入標準庫頭文件
using namespace std; // 使用標準命名空間
#define int long long // 將int類型定義為long long類型,便于處理大數
#define endl '\n' // 將endl定義為換行符// 定義一個結構體node,用來存儲一個分配方案及其總成本
struct node {vector<int>people = { 0,0,0,0 }; // 分配方案int total = 0; // 總成本
};// 定義成本矩陣
vector<vector<int>> cost = {{9,2,7,8},{6,4,3,7},{5,8,1,8},{7,6,9,4}
};// 定義一個包含任務序號的數組
vector<int>arr = { 1,2,3,4 };
// 定義一個變量ret,用來存儲最優方案
node ret;// 初始化函數
void init() {ret.total = INT_MAX; // 將最優方案的總成本初始化為最大值
}// 求解任務分配問題的函數
void solve() {do {node temp; // 定義一個臨時變量temp來存儲當前分配方案for (int i = 0; i < arr.size(); i++) { // 遍歷所有任務temp.total += cost[i][arr[i] - 1]; // 累加當前分配方案的總成本}temp.people = arr; // 將當前分配方案賦值給temp的people字段if (ret.total > temp.total) ret = temp; // 如果當前分配方案的總成本小于最優方案的總成本,則更新最優方案} while (next_permutation(arr.begin(), arr.end())); // 生成下一個排列printf("最優方案:\n"); // 輸出最優方案for (int i = 0; i < 4; i++) { // 遍歷所有人printf("第%lld個人安排任務%lld\n", i + 1, ret.people[i]); // 輸出每個人對應的任務}printf("總成本=%lld\n", ret.total); // 輸出總成本
}// 主函數
signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高輸入輸出效率init(); // 初始化solve(); // 求解任務分配問題
}#endif // 1

結尾

最后,感謝您閱讀我的文章,希望這些內容能夠對您有所啟發和幫助。如果您有任何問題或想要分享您的觀點,請隨時在評論區留言。

同時,不要忘記訂閱我的博客以獲取更多有趣的內容。在未來的文章中,我將繼續探討這個話題的不同方面,為您呈現更多深度和見解。

謝謝您的支持,期待與您在下一篇文章中再次相遇!

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

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

相關文章

pymysql.err.OperationalError: (1030, ‘Got error 168 from storage engine‘)

錯誤 pymysql.err.OperationalError: (1030, Got error 168 from storage engine) 通常與MySQL的InnoDB存儲引擎相關&#xff0c;它指示你試圖進行的操作超出了存儲引擎的能力或資源限制。具體來說&#xff0c;MySQL錯誤代碼168&#xff08;或“ER_TABLE_NEEDS_UPGRADE”&#…

[處理器芯片]-6 超標量CPU實現之浮點運算

1 浮點運算單元FPU 超標量CPU中的浮點運算單元是專門處理浮點數運算的關鍵組件。浮點運算單元的設計涉及多個復雜的子模塊和技術&#xff0c;以保證高效、準確地執行浮點數的加減法、乘法、除法、平方根等操作。 1&#xff09;浮點數術語 浮點數通常采用IEEE 754標準表示&…

顯示IPS技術

顯示器的IPS&#xff08;In-Plane Switching&#xff0c;平面轉換&#xff09;技術是一種先進的液晶面板技術&#xff0c;由日立公司在2001年推出。該技術優化了液晶分子的排列方式&#xff0c;采取水平排列&#xff0c;使得分子結構在遇到外界壓力時仍能保持穩定&#xff0c;不…

第 33 次CCF認證

1. 詞頻統計 題目描述 樣例輸入 代碼 #include <bits/stdc.h>using namespace std;int main() {int n,m;cin>>n>>m;vector<int> ans1(m,0),ans2(m,0);while (n --) {int t;cin>>t;vector<int> vis(m1,0);for (int i 1;i < t;i ) {i…

python去除html中<div>等

用beautifulsoup并不能將全部的去除得到剩余的txt&#xff0c;特別在興趣段找關鍵字的時候。 使用re模塊可以實現這個功能。 for a in a_d:em_name str(a.find(em))pattern re.compile(r<[^>]>, re.S)result pattern.sub(, em_name)result result.strip(\n)name_…

Spring Boot 中的HTTP請求方式詳解:優缺點與代碼示例

在Spring Boot中&#xff0c;有多種方式可以發起HTTP請求。主要的工具包括RestTemplate、WebClient和增強的AsyncRestTemplate。本文將詳細介紹每種請求方式及其優缺點&#xff0c;并給出代碼示例。 1. RestTemplate RestTemplate 是 Spring 提供的一個用于同步 HTTP 請求的客…

vxe-table v4 ~ v4.6 升級到 v4.7+ 版本

vxe-table v4 ~ v4.6 升級到 v4.7 版本 更新日志 vxe-table 4.7 分離了 vxe-table 表格和 vxe-pc-ui 組件庫 變動如下 全局安裝 // ... import VxeUITable from vxe-table import vxe-table/lib/style.css // ...createApp(App).use(VxeUITable).mount(#app)修改后 // ...i…

數據結構(五)

數據結構&#xff08;五&#xff09; 常見的排序算法內部排序交換插入選擇歸并基數 外部排序基于歸并的 常見的排序算法 內部排序 交換 冒泡&#xff1a;每一次運行總會將最小的或者最大的放到前面&#xff0c;如果需要交換&#xff0c;一直在交換 快速排序*&#xff1a;經過…

【java程序設計期末復習】chapter5 子類的繼承

子類的繼承 繼承是一種由已有的類創建新類的機制。利用繼承&#xff0c;我們可以先創建一個共有屬性的一般類&#xff0c;根據該一般類再創建具有特殊屬性的新類&#xff0c;新類繼承一般類的狀態和行為&#xff0c;并根據需要增加它自己的新的狀態和行為。由繼承而得到的類稱…

Git分支的操作詳解(查看、新增、切換、合并、刪除)

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

2024最新前端面試八股文【基礎篇293題】

?、HTML、HTTP、web綜合問題 1 前端需要注意哪些SEO 2 <img> 的 title 和 alt 有什么區別 3 HTTP的?種請求?法?途 4 從瀏覽器地址欄輸?url到顯示??的步驟 5 如何進??站性能優化 6 HTTP狀態碼及其含義 7 語義化的理解 8 介紹?下你對瀏覽器內核的理解 9 …

【操作系統】發展與分類(手工操作、批處理、分時操作、實時操作)

2.操作系統發展與分類 思維導圖 手工操作階段&#xff08;此階段無操作系統&#xff09; 需要人工干預 缺點&#xff1a; 1.用戶獨占全機&#xff0c;資源利用率低&#xff1b; 2.CPU等待手工操作&#xff0c;CPU利用不充分。 批處理階段&#xff08;操作系統開始出現&#x…

鏈表-線性表的鏈式表示

鏈表-線性表的鏈式表示 #mermaid-svg-ozpXrKnNCyYdqHvN {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ozpXrKnNCyYdqHvN .error-icon{fill:#552222;}#mermaid-svg-ozpXrKnNCyYdqHvN .error-text{fill:#552222;stro…

express 設定路徑別名

在使用ts情況下 pnpm i -D tsconfig-paths配置tsconfig.json {// 引入 tsconfig-paths/register// 注意 ts-node 的層級與 compilerOptions 相同"ts-node": {"require": ["tsconfig-paths/register"]},"compilerOptions": {// ...//…

width: auto 和 width: 100% 的區別

width: auto Vs. width: 100% 關于 width 屬性 CSS 中的 width 屬性用于設置元素的寬度。默認情況下&#xff0c;width 設置的是內容區&#xff08;content area&#xff09;的寬度。如果元素有樣式 box-sizing: border-box&#xff0c;則 width 設置的是邊框區&#xff08;bo…

正運動控制器:視覺糾偏和找孔

一、用戶主界面CCD參數設置 通過主界面CCD參數設置&#xff0c;學習如何操作計算相機中心與電批中心的偏移量&#xff0c;以及相機標定的功能。 1、相機中心與電批中心的偏移量計算 1.1、在用戶主界面點擊CCD參數按鈕&#xff0c;進入CCD設置界面。 主界面 CCD參數設置界面 1…

制作電子畫冊速成攻略,快來試試

?當今社會&#xff0c;數字媒體日益普及&#xff0c;電子畫冊作為一種嶄新的展示方式&#xff0c;受到了越來越多人的青睞。它不僅形式新穎&#xff0c;互動性強&#xff0c;而且制作起來也并不復雜。想知道如何快速掌握制作電子畫冊的技巧嗎&#xff1f;我來教你吧。 接下來&…

二叉樹的廣義表反序列化

前言 個人小記 一、代碼 #include<stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_NODE 10 #define MAX_LEN 100 #define key(n)(n)?(n->key):(-1) typedef struct Node {int key;struct Node* lchild,*rchil…

Leetcode 3159. Find Occurrences of an Element in an Array

Leetcode 3159. Find Occurrences of an Element in an Array 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3159. Find Occurrences of an Element in an Array 1. 解題思路 這一題的話我們只需要首先統計一下array當中目標元素x出現在第幾次的位置&#xff0c;構造一個has…