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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2018.01.01(数字三角形,最长上升子序列等)

發布時間:2023/12/13 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2018.01.01(数字三角形,最长上升子序列等) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2017.12.24

?簡單的動態規劃

1.數字三角形(算法引入)

題目描述:下圖所示是一個數字三角形,其中三角形中的數值為正整數,現規定從最頂層往下走到最底層,每一步可沿左斜線向下或右斜線向下走。設三角形有n層,編程計算出從頂層到底層的一條路徑,使得該路徑上的和最大,輸出最大值。(n<=100)

思路&&代碼(搜索回溯):

最顯而易見的思路,既然要求一條最短的路徑,最簡單的方法就是遍歷所有的路徑,找到一條最優的。時間復雜度是O(2n)以下是搜索代碼。

1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int map[101][101],n; 5 int count=0,ans=-20180101; 6 void search(int x,int y){ 7   count+=map[x][y]; 8   if(x==n){ 9     if(count>ans)ans=count; 10   } 11   else{ 12   search(x+1,y+1); 13   search(x+1,y); 14   } 15   count-=map[x][y]; 16 } 17 int main(){ 18   scanf("%d",&n); 19   int i,j; 20   for(i=1;i<=n;i++){ 21     for(j=1;j<=i;j++){ 22       scanf("%d",&map[i][j]); 23     } 24   } 25   search(1,1); 26   printf("%d\n",ans); 27   return 0; 28 } View Code

思路&&代碼(分治法):

對于任意一個點,我們可以把它的最大值和看成Max(sum[i+1][j],[i+1][j+1]),分解為兩個規模更小的子問題。但是本質上和搜索沒有區別,所以時間復雜度還是O(2n)。

1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int n,map[101][101]; 5 int fenzhi(int x,int y){ 6   if(x==n)return map[x][y]; 7   int zi1,zi2,_max; 8   zi1=fenzhi(x+1,y); 9   zi2=fenzhi(x+1,y+1); 10   if(zi1<=zi2)_max=zi2; 11   else _max=zi1; 12   return _max+map[x][y]; 13 } 14 int main(){ 15   scanf("%d",&n); 16   int i,j; 17   for(i=1;i<=n;i++){ 18     for(j=1;j<=i;j++){ 19       scanf("%d",&map[i][j]); 20     } 21   } 22   printf("%d",fenzhi(1,1)); 23   return 0; 24 } View Code

思路&&代碼(記憶化):

比搜索要更優。我們注意到,不管是搜索還是分治,它們都是O(2n)的時間復雜度,是因為它們算了一些重復的東西。既然有重復,那我就把這些重復算的東西用一個數組保存起來,要用時就不用再去算一遍,只要調用了。所以把時間復雜度大大提升了,只有O(n2)了。

1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int map[101][101],book[101][101]; 5 int n; 6 int max(int x,int y){ 7   if(y>x) 8     return y; 9   else 10     return x; 11 } 12 int search(int r,int c){ 13   int ans; 14   if (r==n) return map[r][c]; 15   if (book[r+1][c]==-1) 16     book[r+1][c]=search(r+1,c); 17   if (book[r+1][c+1]==-1) 18     book[r+1][c+1]=search(r+1,c+1); 19   ans=max(book[r+1][c],book[r+1][c+1])+book[r][c]; 20   return ans; 21 } 22 int main(){ 23   scanf("%d",&n); 24   int i,j; 25   for(i=1;i<=n;i++){ 26     for(j=1;j<=i;j++){ 27       scanf("%d",&map[i][j]); 28       book[i][j]=-1; 29     } 30   } 31   printf("%d",search(1,1)); 32   return 0; 33 } View Code

思路&&代碼(動態規劃):

自底向上。第i層的任意一個點,其最大值是它自己加上它下一層的兩個點的最大值之和。用i表示行,j表示列,狀態轉移方程如下。這樣,時間復雜度也只有O(2n)。

1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int map[101][101],book[101][101]; 5 int max(int x,int y){ 6   if(x>y)return x; 7   else return y; 8 } 9 int main(){ 10   int n; 11   scanf("%d",&n); 12   int i,j; 13   for(i=1;i<=n;i++){ 14     for(j=1;j<=i;j++){ 15       scanf("%d",&map[i][j]); 16     } 17   } 18   for(j=1;j<=n;j++) 19     book[n][j]=map[n][j]; 20   for(i=n-1;i>=1;i--) 21     for(j=1;j<=i;j++) 22      book[i][j]=max(book[i+1][j+1],book[i+1][j])+map[i][j]; 23        printf("%d",book[1][1]); 24   return 0; 25 } View Code

2.最長上升子序列

思路:

對于以第i個數為右端點的一個序列,他本身就是一個長度為1的上升子序列。這時,如果它的右邊有比它數值更小的數,這時的最長上升子序列就是這個元素本身的長度1和以他前面的比他數值更小的這個元素為右端點的最長上升子序列的長度和。

狀態轉移方程:sum[i]=_Max(sum[i],sum[j]+1); ?(j<i,num[j]<num[i])

核心代碼:

1 sum[1]=1; 2 for(i=2;i<=n;i++){ 3 sum[i]=1; 4 for(j=1;j<i;j++){ 5 if(num[j]<num[i]){ 6 sum[i]=_Max(sum[i],sum[j]+1); 7 } 8 } 9 } 10 for(i=1;i<=n;i++) 11 max=_Max(max,sum[i]); View Code

狀態:AC

轉載于:https://www.cnblogs.com/yzyl-Leo-wey/p/8167768.html

總結

以上是生活随笔為你收集整理的2018.01.01(数字三角形,最长上升子序列等)的全部內容,希望文章能夠幫你解決所遇到的問題。

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