日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法分析与设计-实验二 动态规划算法设计

發布時間:2024/10/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法分析与设计-实验二 动态规划算法设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1、 數字三角問題
    • 2、最長公共子序列問題
    • 3、日常購物
    • 4、臺階問題

一、實驗目的:
掌握動態規劃算法的基本思想及適用條件,掌握動態規劃算法的設計步驟和具體實現。

二、實驗所用儀器及環境
Windows 7 以上操作系統,PC機,codeblocks環境

三、實驗原理:
算法總體思想:動態規劃算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題但是經分解得到的子問題往往不是互相獨立的。不同子問題的數目常常只有多項式量級。在用分治法求解時,有些子問題被重復計算了許多次。如果能夠保存已解決的子問題的答案,而在需要時再找出已求得的答案,就可以避免大量重復計算,從而得到多項式時間算法。
動態規劃算法設計步驟:
(1)找出最優解的性質,并刻劃其結構特征。
(2)遞歸地定義最優值。
(3)以自底向上的方式計算出最優值。
(4)根據計算最優值時得到的信息,構造最優解。

四、實驗內容:

1、 數字三角問題

問題描述:給定一個由n行數字組成的數字三角形,如下圖所示
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

試設計一個算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。
如上圖最大值為30=7+3+8+7+5

#include <iostream> #include<bits/stdc++.h> using namespace std; int a[100][100]={0}; int mem[100][100]={0}; int n; int memd[100][100]={0}; int dp(int p,int q){if(mem[p][q]!=0){return mem[p][q];}if(p==n){mem[p][q]=a[p][q];return mem[p][q];}if(dp(p+1,q)>=dp(p+1,q+1)){memd[p][q]=q;}else{memd[p][q]=q+1;}mem[p][q]=max(dp(p+1,q),dp(p+1,q+1))+a[p][q];return mem[p][q]; }int main() {cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){cin>>a[i][j];}}//cout<<dp(1,1)<<"=";int qt,pt;qt=pt=1;for(int i=1;i<=n;i++){cout<<a[i][pt];if(i!=n){cout<<"+";}pt=memd[i][pt];}return 0; } //in //5 //7 //3 8 //8 1 0 //2 7 4 4 //4 5 2 6 5 //out //30

2、最長公共子序列問題

問題描述:給定兩個序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最長公共子序列。
輸入:
第1行:兩個子序列的長度,m n
第2行:第1個子序列的各個元素(序列下標從1開始)
第3行:第2個子序列的各個元素(序列下標從1開始)
輸出:
最長公共子序列
實例:
輸入:
第1行:
4 5 //m和n的值
第2行
abad //輸入4個字符,下標從1開始
第3行
baade //輸入5個字符,下標從1開始
輸出:
Aad

#include<bits/stdc++.h> using namespace std; int recdp[1000][1000]= {0};char str1[1000]; char str2[1000];int dp(int i,int j) {///讓數組頭從開始,dp0,與dp,0都代表空串///baseif(i==0||j==0)return 0;///recif(recdp[i][j]!=0){return recdp[i][j];}///相同時直接+1/// 當這里直接使用圖中的0為空字符串時,一定記得,str也是從0開始計算的,所以第五個字符應該是str[4]//if(str1[i-1]==str2[j-1]){recdp[i][j]=dp(i-1,j-1)+1;return recdp[i][j];}else{///不同時直接選大的(我也不知道誰大,那就比比吧)(可能,要1,可能要2,****可能都不要) ///不需要兩個都不要,兩個都不要的話,第一次不要1,第二次不要2就行了,而且也不會,因為兩個都不要一定是最小的 ///*******不同時不要+1recdp[i][j]=max(dp(i-1,j),dp(i,j-1));return recdp[i][j];}return 0; } int main() {//cout << "Hello world!" << endl;cin>>str1;cin>>str2;cout<<dp(strlen(str1),strlen(str2));return 0;}///abcde ///ace ///out //3

3、日常購物

問題描述:小明今天很開心,因為在家買的新房子即將拿到鑰匙。新房里面有一間他自己專用的、非常寬敞的房間。讓他更高興的是,他的母親昨天對他說:“你的房間需要購買什么物品?怎么布置,你說了算,只要他們的價格總和不超過N元錢”。小明今天早上開始預算,但他想買太多的東西,肯定會超過母親的N元限額。因此,他把對每件物品的渴望程度,分為5等級:用整數1->5表示,第5等表示最想要。他還從互聯網上找到了每件商品(所有整數)的價格。他希望在不超過N元(可能等于N元)的情況下,將每件商品的價格與效益度的乘積的總和最大化.
設第j件物品的價格為p[j],重要度為w[j],其選中的k件商品,編號依次為j1,j2,……,jk,則所求的總和為:
p[j1]×w[j1]+p[j2]×w[j2]+ …+p[jk]×w[jk]。
請幫小明設計一個符合要求的購物清單。
其中N=2000,K=6
p[1]=200 w[1]=2
p[2]=300 w[2]=2
p[3]=600 w[3]=1
p[4]=400 w[4]=3
p[5]=1000 w[5]=4
p[6]=800 w[6]=5

#include <iostream> #include<bits/stdc++.h> using namespace std; int p[10000]={0}; int w[10000]={0}; int mem[10000]={0};int dp(int n,int k){for(int i=0;i<k;i++){for(int j=n;j>=p[i];j--){mem[j]=max(mem[j],mem[j-p[i]]+p[i]*w[i]);}}return mem[n]; } int main() {int n,k;cin>>n>>k;for(int i=0;i<k;i++){cin>>p[i]>>w[i];}cout<<dp(n,k);return 0; } //in //2000 6 //200 2 //300 2 //600 1 //400 3 //1000 4 //800 5 //out //8400

4、臺階問題

問題描述:有n級臺階,一個人每次上一級或者兩級,問有多少種走完n級臺階的方法。
實際情況:給定一個矩陣m,從左上角開始每次只能向右走或者向下走,最后達到右下角的位置,路徑中所有數字累加起來就是路徑和,返回所有路徑的最小路徑和,如果給定的m如下,那么路徑1,3,1,0,6,1,0就是最小路徑和,返回12.
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0

#include <iostream> #include<bits/stdc++.h> using namespace std; int mem[1000]={0}; int dp(int n) {if(n==1){return 1;}if(n==2){return 2;}if(mem[n]!=0){return mem[n];}mem[n]=dp(n-1)+dp(n-2);return mem[n]; } int main() {int n;cin>>n;cout<<dp(n);return 0; } //in //12 //233

五、實驗結果與分析:
通過運行程序驗證程序的正確性,給出程序運行結果,分析程序出現的bug的原因,調試程序過程種出現的錯誤和解決方法。

總結

以上是生活随笔為你收集整理的算法分析与设计-实验二 动态规划算法设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。